File: test_ast_parsing.py

package info (click to toggle)
python-pegen 0.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,980 kB
  • sloc: python: 15,064; makefile: 89
file content (110 lines) | stat: -rw-r--r-- 3,328 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""Test pure Python parser against cpython parser."""
import ast
import difflib
import io
import sys
import textwrap
import tokenize
from pathlib import Path

import pytest


@pytest.mark.parametrize(
    "filename",
    [
        pytest.param(
            "advanced_decorators.py",
            marks=pytest.mark.skipif(
                sys.version_info < (3, 9), reason="Valid only in Python 3.9+"
            ),
        ),
        "assignment.py",
        "async.py",
        "call.py",
        "comprehensions.py",
        "expressions.py",
        "fstrings.py",
        "function_def.py",
        "imports.py",
        "lambdas.py",
        pytest.param(
            "multi_statement_per_line.py",
            marks=pytest.mark.skipif(
                sys.version_info < (3, 9), reason="Col offset match only on Python 3.9+"
            ),
        ),
        "no_newline_at_end_of_file.py",
        "no_newline_at_end_of_file_with_comment.py",
        pytest.param(
            "pattern_matching.py",
            marks=pytest.mark.skipif(
                sys.version_info < (3, 10), reason="Valid only in Python 3.10+"
            ),
        ),
        "simple_decorators.py",
        "statements.py",
        pytest.param(
            "try_except_group.py",
            marks=pytest.mark.skipif(
                sys.version_info <= (3, 11), reason="except* allowed only in Python 3.11+"
            ),
        ),
        pytest.param(
            "type_params.py",
            marks=pytest.mark.skipif(
                sys.version_info <= (3, 12),
                reason="type declarations allowed only in Python 3.12+",
            ),
        ),
        pytest.param(
            "with_statement_multi_items.py",
            marks=pytest.mark.skipif(
                sys.version_info < (3, 9),
                reason="Parenthesized with items allowed only in Python 3.9+",
            ),
        ),
    ],
)
def test_parser(python_parse_file, python_parse_str, filename):
    path = Path(__file__).parent / "data" / filename
    with open(path) as f:
        source = f.read()

    for part in source.split("\n\n\n"):
        original = ast.parse(part)

        kwargs = dict(include_attributes=True)
        if sys.version_info >= (3, 9):
            kwargs["indent"] = "  "

        try:
            pp_ast = python_parse_str(part, "exec")
        except Exception:
            temp = io.StringIO(part)
            print("Parsing failed:")
            print("Source is:")
            print(textwrap.indent(part, "  "))
            temp = io.StringIO(part)
            print("Token stream is:")
            for t in tokenize.generate_tokens(temp.readline):
                print(t)
            print()
            print("CPython ast is:")
            print(ast.dump(original, **kwargs))
            raise

        o = ast.dump(original, **kwargs)
        p = ast.dump(pp_ast, **kwargs)
        diff = "\n".join(
            difflib.unified_diff(o.split("\n"), p.split("\n"), "cpython", "python-pegen")
        )
        if diff:
            print(part)
            print(diff)
        assert not diff

    o = ast.dump(ast.parse(source), **kwargs)
    p = ast.dump(python_parse_file(path), **kwargs)
    diff = "\n".join(difflib.unified_diff(o.split("\n"), p.split("\n"), "cpython", "python-pegen"))
    assert not diff