PEP-695: Potentially breaking changes made to __match_args__
attributes of AST nodes · Issue #104799 · python/cpython (original) (raw)
Consider the following script:
import ast
def test(node): match node: case ast.FunctionDef("foo", ast.arguments(args=[ast.arg("bar")])): print('matched! :)') case _: print("Didn't match :(")
source = ast.parse("def foo(bar): pass") node = source.body[0] assert isinstance(node, ast.FunctionDef) test(node)
Running this script on 3.11 gets you this output:
>python repro.py
matched! :)
Running this script on CPython main
, however, gets you this output:
>python repro.py
Didn't match :(
The reason for this is that the implementation of PEP-695 (new in Python 3.12) added a number of new AST nodes to Python, and as a result, the __match_args__
attributes of ast.FunctionDef
, ast.AsyncFunctionDef
and ast.ClassDef
are all different on 3.12 compared to what they were on 3.11.
`__match_args__` attributes on 3.11:
import ast for node in ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef: ... print(node.match_args) ... ('name', 'bases', 'keywords', 'body', 'decorator_list') ('name', 'args', 'body', 'decorator_list', 'returns', 'type_comment') ('name', 'args', 'body', 'decorator_list', 'returns', 'type_comment')
`__match_args__` attributes on 3.12:
import ast for node in ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef: ... print(node.match_args) ... ('name', 'type_params', 'bases', 'keywords', 'body', 'decorator_list') ('name', 'type_params', 'args', 'body', 'decorator_list', 'returns', 'type_comment') ('name', 'type_params', 'args', 'body', 'decorator_list', 'returns', 'type_comment')
This feels like it has the potential to be quite a breaking change for people using pattern-matching to parse ASTs. It would probably be okay if type_params
had been added as the final item in the __match_args__
tuples, but at the moment it comes in second place.
Cc. @JelleZijlstra for PEP-695. Also curious if @brandtbucher has any thoughts (for pattern-matching expertise) or @isidentical (for ast
-module expertise).
Linked PRs
- gh-104799: Move location of type_params AST fields #104828
- gh-104799: Default missing lists in AST to the empty list #104834
- [3.12] gh-104799: Move location of type_params AST fields (GH-104828) #104974
- [3.12] gh-104799: Default missing lists in AST to the empty list (GH-104834) #105213
- gh-104799: PEP 695 backward compatibility for ast.unparse #105846
- [3.12] gh-104799: PEP 695 backward compatibility for ast.unparse (GH-105846) #105862