pytest-dev / pytest-bdd

BDD library for the pytest runner
https://pytest-bdd.readthedocs.io/en/latest/
MIT License
1.31k stars 221 forks source link

Escaping issue in one test with Python 3.12 #621

Closed musicinmybrain closed 1 year ago

musicinmybrain commented 1 year ago

The test test_step_functions_same_parser fails, and the test module test_step_functions_same_parser.py errors, while testing pytest-bdd 6.1.1 on Python 3.12:

=================================== FAILURES ===================================
_______________________ test_step_functions_same_parser ________________________

pytester = <Pytester PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_step_functions_same_parser0')>

    def test_step_functions_same_parser(pytester):
        pytester.makefile(
            ".feature",
            target_fixture=textwrap.dedent(
                """\
                Feature: A feature
                    Scenario: A scenario
                        Given there is a foo with value "(?P<value>\\w+)"
                        And there is a foo with value "testfoo"
                        When pass
                        Then pass
                """
            ),  
        )   
        pytester.makepyfile(
            textwrap.dedent(
                """\
            import pytest
            from pytest_bdd import given, when, then, scenarios, parsers
            from pytest_bdd.utils import dump_obj

            scenarios("target_fixture.feature")

            STEP = 'there is a foo with value "(?P<value>\\w+)"'

            @given(STEP)
            def _():
                dump_obj(('str',))

            @given(parsers.re(STEP))
            def _(value):
                dump_obj(('re', value))

            @when("pass")
            @then("pass")
            def _():
                pass
            """
            )
        )
        result = pytester.runpytest("-s")
>       result.assert_outcomes(passed=1)
E       AssertionError: assert {'passed': 0, 'skipped': 0, 'failed': 0, 'errors': 1, 'xpassed': 0, 'xfailed': 0} == {'passed': 1, 'skipped': 0, 'failed': 0, 'errors': 0, 'xpassed': 0, 'xfailed': 0}
E         Common items:
E         {'failed': 0, 'skipped': 0, 'xfailed': 0, 'xpassed': 0}
E         Differing items:
E         {'errors': 1} != {'errors': 0}
E         {'passed': 0} != {'passed': 1}
E         Full diff:
E           {
E         -  'errors': 0,
E         ?            ^
E         +  'errors': 1,
E         ?            ^
E            'failed': 0,
E         -  'passed': 1,
E         ?            ^
E         +  'passed': 0,
E         ?            ^
E            'skipped': 0,
E            'xfailed': 0,
E            'xpassed': 0,
E           }

pytester   = <Pytester PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_step_functions_same_parser0')>
result     = <RunResult ret=2 len(stdout.lines)=36 len(stderr.lines)=0 duration=0.13s>

/builddir/build/BUILD/pytest-bdd-6.1.1/_empty/tests/steps/test_common.py:122: AssertionError
----------------------------- Captured stdout call -----------------------------
============================= test session starts ==============================
platform linux -- Python 3.12.0b3, pytest-7.3.2, pluggy-1.0.0
rootdir: /tmp/pytest-of-mockbuild/pytest-0/test_step_functions_same_parser0
plugins: bdd-6.1.1, xdist-3.3.1   
collected 0 items / 1 error

==================================== ERRORS ====================================
_____________ ERROR collecting test_step_functions_same_parser.py ______________
/usr/lib/python3.12/site-packages/_pytest/python.py:617: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
/usr/lib/python3.12/site-packages/_pytest/pathlib.py:564: in import_path
    importlib.import_module(module_name)
/usr/lib64/python3.12/importlib/__init__.py:90: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
<frozen importlib._bootstrap>:1293: in _gcd_import
    ???
<frozen importlib._bootstrap>:1266: in _find_and_load
    ???
<frozen importlib._bootstrap>:1237: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:841: in _load_unlocked
    ???
/usr/lib/python3.12/site-packages/_pytest/assertion/rewrite.py:169: in exec_module
    source_stat, co = _rewrite_test(fn, self.config)
/usr/lib/python3.12/site-packages/_pytest/assertion/rewrite.py:351: in _rewrite_test
    tree = ast.parse(source, filename=strfn)
/usr/lib64/python3.12/ast.py:52: in parse
    return compile(source, filename, mode, flags,
E     File "/tmp/pytest-of-mockbuild/pytest-0/test_step_functions_same_parser0/test_step_functions_same_parser.py", line 7
E       STEP = 'there is a foo with value "(?P<value>\w+)"'
E              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E   SyntaxError: invalid escape sequence '\w'
=========================== short test summary info ============================
ERROR test_step_functions_same_parser.py
!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
=============================== 1 error in 0.10s ===============================
=========================== short test summary info ============================
FAILED tests/steps/test_common.py::test_step_functions_same_parser - Assertio...
======================== 1 failed, 118 passed in 8.50s =========================

I observed this while trying to rebuild the python-pytest-bdd package in Fedora Linux Rawhide for Python 3.12. In theory, you should be able to reproduce this with the tox environment py312-pytestlatest-coverage, but I’m currently having issues running the tests that way due to TypeError: type 'typing.TypeVar' is not an acceptable base type raised from typing-extensions.

There are enough layers of escaping here that it wasn’t immediately obvious to me what the correct fix was, and a couple of quick attempts didn’t pan out, so I’m reporting the issue and skipping the affected tests rather than offering a PR.

musicinmybrain commented 1 year ago

Found that this is fixed in 628790921e05e614a7064aab29b8c60fc01c943b. Apologies for the noise.