Skip to content

Commit a14c718

Browse files
moajoRonnyPfannschmidtnicoddemus
authored
Fix disable_test_id_escaping_and_forfeit_all_rights_to_community_support option when using pytest.param(..., id="...")
Fixes #9037 --------- Co-authored-by: Ronny Pfannschmidt <[email protected]> Co-authored-by: Bruno Oliveira <[email protected]>
1 parent 23256dd commit a14c718

File tree

6 files changed

+57
-3
lines changed

6 files changed

+57
-3
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ Sviatoslav Sydorenko
408408
Sylvain Marié
409409
Tadek Teleżyński
410410
Takafumi Arakaki
411+
Takumi Otani
411412
Taneli Hukkinen
412413
Tanvi Mehta
413414
Tanya Agarwal

changelog/9037.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Honor :confval:`disable_test_id_escaping_and_forfeit_all_rights_to_community_support` when escaping ids in parametrized tests.

doc/en/reference/reference.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,29 @@ passed multiple times. The expected format is ``name=value``. For example::
13321332
console_output_style = classic
13331333
13341334
1335+
.. confval:: disable_test_id_escaping_and_forfeit_all_rights_to_community_support
1336+
1337+
.. versionadded:: 4.4
1338+
1339+
pytest by default escapes any non-ascii characters used in unicode strings
1340+
for the parametrization because it has several downsides.
1341+
If however you would like to use unicode strings in parametrization
1342+
and see them in the terminal as is (non-escaped), use this option
1343+
in your ``pytest.ini``:
1344+
1345+
.. code-block:: ini
1346+
1347+
[pytest]
1348+
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
1349+
1350+
Keep in mind however that this might cause unwanted side effects and
1351+
even bugs depending on the OS used and plugins currently installed,
1352+
so use it at your own risk.
1353+
1354+
Default: ``False``.
1355+
1356+
See :ref:`parametrizemark`.
1357+
13351358
.. confval:: doctest_encoding
13361359

13371360

src/_pytest/mark/structures.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import warnings
2222

2323
from .._code import getfslineno
24-
from ..compat import ascii_escaped
2524
from ..compat import NOTSET
2625
from ..compat import NotSetType
2726
from _pytest.config import Config
@@ -97,7 +96,6 @@ def param(
9796
if id is not None:
9897
if not isinstance(id, str):
9998
raise TypeError(f"Expected id to be a string, got {type(id)}: {id!r}")
100-
id = ascii_escaped(id)
10199
return cls(values, marks, id)
102100

103101
@classmethod

src/_pytest/python.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ def _resolve_ids(self) -> Iterable[str]:
924924
for idx, parameterset in enumerate(self.parametersets):
925925
if parameterset.id is not None:
926926
# ID provided directly - pytest.param(..., id="...")
927-
yield parameterset.id
927+
yield _ascii_escaped_by_config(parameterset.id, self.config)
928928
elif self.ids and idx < len(self.ids) and self.ids[idx] is not None:
929929
# ID provided in the IDs list - parametrize(..., ids=[...]).
930930
yield self._idval_from_value_required(self.ids[idx], idx)

testing/python/metafunc.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,37 @@ def getini(self, name):
625625
).make_unique_parameterset_ids()
626626
assert result == [expected]
627627

628+
def test_idmaker_with_param_id_and_config(self) -> None:
629+
"""Unit test for expected behavior to create ids with pytest.param(id=...) and
630+
disable_test_id_escaping_and_forfeit_all_rights_to_community_support
631+
option (#9037).
632+
"""
633+
634+
class MockConfig:
635+
def __init__(self, config):
636+
self.config = config
637+
638+
def getini(self, name):
639+
return self.config[name]
640+
641+
option = "disable_test_id_escaping_and_forfeit_all_rights_to_community_support"
642+
643+
values: list[tuple[Any, str]] = [
644+
(MockConfig({option: True}), "ação"),
645+
(MockConfig({option: False}), "a\\xe7\\xe3o"),
646+
]
647+
for config, expected in values:
648+
result = IdMaker(
649+
("a",),
650+
[pytest.param("string", id="ação")],
651+
None,
652+
None,
653+
config,
654+
None,
655+
None,
656+
).make_unique_parameterset_ids()
657+
assert result == [expected]
658+
628659
def test_idmaker_duplicated_empty_str(self) -> None:
629660
"""Regression test for empty strings parametrized more than once (#11563)."""
630661
result = IdMaker(

0 commit comments

Comments
 (0)