Skip to content

Commit

Permalink
Fix `disable_test_id_escaping_and_forfeit_all_rights_to_community_sup…
Browse files Browse the repository at this point in the history
…port` option when using `pytest.param(..., id="...")`

Fixes #9037

---------

Co-authored-by: Ronny Pfannschmidt <[email protected]>
Co-authored-by: Bruno Oliveira <[email protected]>
  • Loading branch information
3 people authored Oct 9, 2024
1 parent 23256dd commit a14c718
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 3 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ Sviatoslav Sydorenko
Sylvain Marié
Tadek Teleżyński
Takafumi Arakaki
Takumi Otani
Taneli Hukkinen
Tanvi Mehta
Tanya Agarwal
Expand Down
1 change: 1 addition & 0 deletions changelog/9037.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Honor :confval:`disable_test_id_escaping_and_forfeit_all_rights_to_community_support` when escaping ids in parametrized tests.
23 changes: 23 additions & 0 deletions doc/en/reference/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,29 @@ passed multiple times. The expected format is ``name=value``. For example::
console_output_style = classic
.. confval:: disable_test_id_escaping_and_forfeit_all_rights_to_community_support

.. versionadded:: 4.4

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
and see them in the terminal as is (non-escaped), use this option
in your ``pytest.ini``:

.. code-block:: ini
[pytest]
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
Keep in mind however 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.

Default: ``False``.

See :ref:`parametrizemark`.

.. confval:: doctest_encoding


Expand Down
2 changes: 0 additions & 2 deletions src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import warnings

from .._code import getfslineno
from ..compat import ascii_escaped
from ..compat import NOTSET
from ..compat import NotSetType
from _pytest.config import Config
Expand Down Expand Up @@ -97,7 +96,6 @@ def param(
if id is not None:
if not isinstance(id, str):
raise TypeError(f"Expected id to be a string, got {type(id)}: {id!r}")
id = ascii_escaped(id)
return cls(values, marks, id)

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ def _resolve_ids(self) -> Iterable[str]:
for idx, parameterset in enumerate(self.parametersets):
if parameterset.id is not None:
# ID provided directly - pytest.param(..., id="...")
yield parameterset.id
yield _ascii_escaped_by_config(parameterset.id, self.config)
elif self.ids and idx < len(self.ids) and self.ids[idx] is not None:
# ID provided in the IDs list - parametrize(..., ids=[...]).
yield self._idval_from_value_required(self.ids[idx], idx)
Expand Down
31 changes: 31 additions & 0 deletions testing/python/metafunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,37 @@ def getini(self, name):
).make_unique_parameterset_ids()
assert result == [expected]

def test_idmaker_with_param_id_and_config(self) -> None:
"""Unit test for expected behavior to create ids with pytest.param(id=...) and
disable_test_id_escaping_and_forfeit_all_rights_to_community_support
option (#9037).
"""

class MockConfig:
def __init__(self, config):
self.config = config

def getini(self, name):
return self.config[name]

option = "disable_test_id_escaping_and_forfeit_all_rights_to_community_support"

values: list[tuple[Any, str]] = [
(MockConfig({option: True}), "ação"),
(MockConfig({option: False}), "a\\xe7\\xe3o"),
]
for config, expected in values:
result = IdMaker(
("a",),
[pytest.param("string", id="ação")],
None,
None,
config,
None,
None,
).make_unique_parameterset_ids()
assert result == [expected]

def test_idmaker_duplicated_empty_str(self) -> None:
"""Regression test for empty strings parametrized more than once (#11563)."""
result = IdMaker(
Expand Down

0 comments on commit a14c718

Please sign in to comment.