-
- Notifications
You must be signed in to change notification settings - Fork 33.6k
Description
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