I know ast.stmt is abstract, and ast.Store is concrete. But how to decide it?
You can test for the _field_types attribute, introduced in Python 3.13.
Prior to Python 3.13, a reasonable heuristic is to test if it has subclasses.
I believe the answer is hinted in your question: ‘stmt’ is lowercase, ‘Store’ is upppercase. Everything defined in abstract grammar is lowercase. All Node classes are uppercase.
Thank you, Ben. Using hasattr(obj, “_field_types”) or obj.__subclasses__() to check.
I am not sure if using ‘uppercase’ to check is reliable. For example, the ast.arguments is a concrete class.
In the abstract grammar, the production rules with variants (look for vertical bars) correspond to abstract classes. Everything else corresponds to a concrete class.
Starting in Python 3.15, the difference is a little more obvious, since attempting to instantiate an abstract node will now raise a deprecation warning:
>>> ast.stmt()
<python-input-1>:1: DeprecationWarning: Instantiating abstract AST node class ast.stmt is deprecated. This will become an error in Python 3.20
stmt()
There’s also the undocumented _ast._is_abstract function (3.15+) that can be used to explicitly check for abstractness:
>>> import _ast
>>> _ast._is_abstract(_ast.stmt)
True
>>> _ast._is_abstract(_ast.Store)
False
(this is an implementation detail from #137865 that may disappear in the future, use at your own risk)