Skip to content

Tests fail with Python 3.12 #222

@s3v-

Description

@s3v-

Hi,
tests fail with python 3.12.1

$ python3.12 -m pytest test/
==================================================================== test session starts ====================================================================
platform linux -- Python 3.12.1, pytest-7.4.4, pluggy-1.3.0
rootdir: /build/parso
configfile: pytest.ini
collected 1348 items                                                                                                                                        

test/test_cache.py .........                                                                                                                          [  0%]
test/test_diff_parser.py ..................................................................................                                           [  6%]
test/test_dump_tree.py ..........                                                                                                                     [  7%]
test/test_error_recovery.py .............                                                                                                             [  8%]
test/test_file_python_errors.py .....                                                                                                                 [  8%]
test/test_fstring.py .....................................................................                                                            [ 13%]
test/test_get_code.py .............                                                                                                                   [ 14%]
test/test_grammar.py .                                                                                                                                [ 14%]
test/test_load_grammar.py ...........                                                                                                                 [ 15%]
test/test_normalizer_issues_files.py .............................                                                                                    [ 17%]
test/test_old_fast_parser.py ...............                                                                                                          [ 19%]
test/test_param_splitting.py .......                                                                                                                  [ 19%]
test/test_parser.py ................................................................................................................................. [ 29%]
.............                                                                                                                                         [ 30%]
test/test_parser_tree.py ...............................................................................                                              [ 35%]
test/test_pep8.py ...                                                                                                                                 [ 36%]
test/test_pgen2.py .................................................................................................................................. [ 45%]
.............................................................................................................................................         [ 56%]
test/test_prefix.py ......................                                                                                                            [ 57%]
test/test_python_errors.py ...........FF............................................................................................................. [ 66%]
............................F....................F..FFF.....FFFFF.............................................................F...................... [ 78%]
.....................................................................................................................................                 [ 87%]
test/test_tokenize.py ............................................................................................................................... [ 97%]
.                                                                                                                                                     [ 97%]
test/test_utils.py ...................................                                                                                                [100%]

========================================================================= FAILURES ==========================================================================
____________________________________________________ test_python_exception_matches[def f(x=3, y): pass] _____________________________________________________

code = 'def f(x=3, y): pass'

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       AssertionError: assert 'SyntaxError: non-default argument follows default argument' in ['SyntaxError: parameter without a default follows parameter with a default']

test/test_python_errors.py:42: AssertionError
______________________________________________________ test_python_exception_matches[lambda x=3, y: x] ______________________________________________________

code = 'lambda x=3, y: x'

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       AssertionError: assert 'SyntaxError: non-default argument follows default argument' in ['SyntaxError: parameter without a default follows parameter with a default']

test/test_python_errors.py:42: AssertionError
__________________________________________________________ test_python_exception_matches[f"{*x}"] ___________________________________________________________

code = 'f"{*x}"'

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert "SyntaxError: f-string: can't use starred expression here" in ["SyntaxError: can't use starred expression here"]

test/test_python_errors.py:42: AssertionError
___________________________________________________________ test_python_exception_matches[f"{}"] ____________________________________________________________

code = 'f"{}"'

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert 'SyntaxError: invalid syntax' in ["SyntaxError: f-string: valid expression required before '}'"]

test/test_python_errors.py:42: AssertionError
___________________________________________________________ test_python_exception_matches[f"{#}"] ___________________________________________________________

code = 'f"{#}"'

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert 'SyntaxError: invalid syntax' in ["SyntaxError: '{' was never closed"]

test/test_python_errors.py:42: AssertionError
__________________________________________________________ test_python_exception_matches[f'{1!b}'] __________________________________________________________

code = "f'{1!b}'"

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert "SyntaxError: f-string: invalid conversion character: expected 's', 'r', or 'a'" in ["SyntaxError: f-string: invalid conversion character 'b': expected 's', 'r', or 'a'"]

test/test_python_errors.py:42: AssertionError
_______________________________________________________ test_python_exception_matches[f'{1:{5:{3}}}'] _______________________________________________________

code = "f'{1:{5:{3}}}'"

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
>       wanted, line_nr = _get_actual_exception(code)

test/test_python_errors.py:35: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

code = "f'{1:{5:{3}}}'"

    def _get_actual_exception(code):
        with warnings.catch_warnings():
            # We don't care about warnings where locals/globals misbehave here.
            # It's as simple as either an error or not.
            warnings.filterwarnings('ignore', category=SyntaxWarning)
            try:
                compile(code, '<unknown>', 'exec')
            except (SyntaxError, IndentationError) as e:
                wanted = e.__class__.__name__ + ': ' + e.msg
                line_nr = e.lineno
            except ValueError as e:
                # The ValueError comes from byte literals in Python 2 like '\x'
                # that are oddly enough not SyntaxErrors.
                wanted = 'SyntaxError: (value error) ' + str(e)
                line_nr = None
            else:
>               assert False, "The piece of code should raise an exception."
E               AssertionError: The piece of code should raise an exception.
E               assert False

test/test_python_errors.py:118: AssertionError
_______________________________________________________ test_python_exception_matches[f'{continue}'] ________________________________________________________

code = "f'{continue}'"

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert 'SyntaxError: f-string: invalid syntax' in ["SyntaxError: f-string: expecting a valid expression after '{'"]

test/test_python_errors.py:42: AssertionError
__________________________________________________________ test_python_exception_matches[f'{1;1}'] __________________________________________________________

code = "f'{1;1}'"

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert 'SyntaxError: f-string: invalid syntax' in ["SyntaxError: f-string: expecting '=', or '!', or ':', or '}'"]

test/test_python_errors.py:42: AssertionError
__________________________________________________________ test_python_exception_matches[f'{a;}'] ___________________________________________________________

code = "f'{a;}'"

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert 'SyntaxError: f-string: invalid syntax' in ["SyntaxError: f-string: expecting '=', or '!', or ':', or '}'"]

test/test_python_errors.py:42: AssertionError
________________________________________________________ test_python_exception_matches[f'{b"" ""}'] _________________________________________________________

code = 'f\'{b"" ""}\''

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       AssertionError: assert 'SyntaxError: f-string: cannot mix bytes and nonbytes literals' in ['SyntaxError: cannot mix bytes and nonbytes literals']

test/test_python_errors.py:42: AssertionError
_________________________________________________________ test_python_exception_matches[f"{'\\n'}"] _________________________________________________________

code = 'f"{\'\\n\'}"'

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
>       wanted, line_nr = _get_actual_exception(code)

test/test_python_errors.py:35: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

code = 'f"{\'\\n\'}"'

    def _get_actual_exception(code):
        with warnings.catch_warnings():
            # We don't care about warnings where locals/globals misbehave here.
            # It's as simple as either an error or not.
            warnings.filterwarnings('ignore', category=SyntaxWarning)
            try:
                compile(code, '<unknown>', 'exec')
            except (SyntaxError, IndentationError) as e:
                wanted = e.__class__.__name__ + ': ' + e.msg
                line_nr = e.lineno
            except ValueError as e:
                # The ValueError comes from byte literals in Python 2 like '\x'
                # that are oddly enough not SyntaxErrors.
                wanted = 'SyntaxError: (value error) ' + str(e)
                line_nr = None
            else:
>               assert False, "The piece of code should raise an exception."
E               AssertionError: The piece of code should raise an exception.
E               assert False

test/test_python_errors.py:118: AssertionError
_________________________________________________________ test_python_exception_matches[f'{1=!b}'] __________________________________________________________

code = "f'{1=!b}'"

    @pytest.mark.parametrize('code', FAILING_EXAMPLES)
    def test_python_exception_matches(code):
        wanted, line_nr = _get_actual_exception(code)
    
        errors = _get_error_list(code)
        actual = None
        if errors:
            error, = errors
            actual = error.message
>       assert actual in wanted
E       assert "SyntaxError: f-string: invalid conversion character: expected 's', 'r', or 'a'" in ["SyntaxError: f-string: invalid conversion character 'b': expected 's', 'r', or 'a'"]

test/test_python_errors.py:42: AssertionError
================================================================== short test summary info ==================================================================
FAILED test/test_python_errors.py::test_python_exception_matches[def f(x=3, y): pass] - AssertionError: assert 'SyntaxError: non-default argument follows default argument' in ['SyntaxError: parameter without a default follows parameter with...
FAILED test/test_python_errors.py::test_python_exception_matches[lambda x=3, y: x] - AssertionError: assert 'SyntaxError: non-default argument follows default argument' in ['SyntaxError: parameter without a default follows parameter with...
FAILED test/test_python_errors.py::test_python_exception_matches[f"{*x}"] - assert "SyntaxError: f-string: can't use starred expression here" in ["SyntaxError: can't use starred expression here"]
FAILED test/test_python_errors.py::test_python_exception_matches[f"{}"] - assert 'SyntaxError: invalid syntax' in ["SyntaxError: f-string: valid expression required before '}'"]
FAILED test/test_python_errors.py::test_python_exception_matches[f"{#}"] - assert 'SyntaxError: invalid syntax' in ["SyntaxError: '{' was never closed"]
FAILED test/test_python_errors.py::test_python_exception_matches[f'{1!b}'] - assert "SyntaxError: f-string: invalid conversion character: expected 's', 'r', or 'a'" in ["SyntaxError: f-string: invalid conversion character 'b': ex...
FAILED test/test_python_errors.py::test_python_exception_matches[f'{1:{5:{3}}}'] - AssertionError: The piece of code should raise an exception.
FAILED test/test_python_errors.py::test_python_exception_matches[f'{continue}'] - assert 'SyntaxError: f-string: invalid syntax' in ["SyntaxError: f-string: expecting a valid expression after '{'"]
FAILED test/test_python_errors.py::test_python_exception_matches[f'{1;1}'] - assert 'SyntaxError: f-string: invalid syntax' in ["SyntaxError: f-string: expecting '=', or '!', or ':', or '}'"]
FAILED test/test_python_errors.py::test_python_exception_matches[f'{a;}'] - assert 'SyntaxError: f-string: invalid syntax' in ["SyntaxError: f-string: expecting '=', or '!', or ':', or '}'"]
FAILED test/test_python_errors.py::test_python_exception_matches[f'{b"" ""}'] - AssertionError: assert 'SyntaxError: f-string: cannot mix bytes and nonbytes literals' in ['SyntaxError: cannot mix bytes and nonbytes literals']
FAILED test/test_python_errors.py::test_python_exception_matches[f"{'\\n'}"] - AssertionError: The piece of code should raise an exception.
FAILED test/test_python_errors.py::test_python_exception_matches[f'{1=!b}'] - assert "SyntaxError: f-string: invalid conversion character: expected 's', 'r', or 'a'" in ["SyntaxError: f-string: invalid conversion character 'b': ex...
============================================================== 13 failed, 1335 passed in 4.08s ==============================================================

Assertion error "The piece of code should raise an exception." is due to Python 3.12 allows backslash in f-strings

PEP 701: Syntactic formalization of f-strings

[PEP 701](https://peps.python.org/pep-0701/) lifts some restrictions on the usage of f-strings.   
Expression components inside f-strings can now be any valid Python expression, including strings reusing the same   
quote as the containing f-string, multi-line expressions, comments, backslashes, and unicode escape sequences.

https://docs.python.org/3/whatsnew/3.12.html

Kind Regards

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions