diff --git a/AUTHORS b/AUTHORS index d6f6ce828..ea6fc5cac 100644 --- a/AUTHORS +++ b/AUTHORS @@ -242,6 +242,7 @@ Vidar T. Fauske Virgil Dupras Vitaly Lashmanov Vlad Dragos +Volodymyr Piskun Wil Cooley William Lee Wim Glenn diff --git a/changelog/2482.feature b/changelog/2482.feature new file mode 100644 index 000000000..37d5138bf --- /dev/null +++ b/changelog/2482.feature @@ -0,0 +1 @@ +Include new ``disable_test_id_escaping_and_forfeit_all_rights_to_community_support`` option to disable ascii-escaping in parametrized values. This may cause a series of problems and as the name makes clear, use at your own risk. diff --git a/doc/en/parametrize.rst b/doc/en/parametrize.rst index 9a237dcd7..912ae1898 100644 --- a/doc/en/parametrize.rst +++ b/doc/en/parametrize.rst @@ -81,6 +81,21 @@ them in turn: test_expectation.py:8: AssertionError ==================== 1 failed, 2 passed in 0.12 seconds ==================== +.. note:: + + pytest by default escapes any non-ascii characters used in unicode strings + for the parametrization because it has several downsides. + If however you would like to use unicode strings in parametrization, use this option in your ``pytest.ini``: + + .. code-block:: ini + + [pytest] + disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True + + to disable this behavior, but keep in mind that this might cause unwanted side effects and + even bugs depending on the OS used and plugins currently installed, so use it at your own risk. + + As designed in this example, only one pair of input/output values fails the simple test function. And as usual with test function arguments, you can see the ``input`` and ``output`` values in the traceback. diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 5b289c7c8..8532837a5 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -102,6 +102,13 @@ def pytest_addoption(parser): default=["test"], help="prefixes or glob names for Python test function and method discovery", ) + parser.addini( + "disable_test_id_escaping_and_forfeit_all_rights_to_community_support", + type="bool", + default=False, + help="disable string escape non-ascii characters, might cause unwanted " + "side effects(use at your own risk)", + ) group.addoption( "--import-mode", @@ -1156,6 +1163,16 @@ def _find_parametrized_scope(argnames, arg2fixturedefs, indirect): return "function" +def _disable_escaping(val, config=None): + if config is None: + escape_option = False + else: + escape_option = config.getini( + "disable_test_id_escaping_and_forfeit_all_rights_to_community_support" + ) + return val if escape_option else ascii_escaped(val) + + def _idval(val, argname, idx, idfn, item, config): if idfn: try: @@ -1177,7 +1194,7 @@ def _idval(val, argname, idx, idfn, item, config): return hook_id if isinstance(val, STRING_TYPES): - return ascii_escaped(val) + return _disable_escaping(val) elif isinstance(val, (float, int, bool, NoneType)): return str(val) elif isinstance(val, REGEX_TYPE):