How to decide a class of the AST module is abstract or concrete?

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)