Skip to content

More accurate annotation for ClassVar AST._field_types #14245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hunterhogan opened this issue Jun 9, 2025 · 0 comments
Closed

More accurate annotation for ClassVar AST._field_types #14245

hunterhogan opened this issue Jun 9, 2025 · 0 comments

Comments

@hunterhogan
Copy link
Contributor

My amateur analysis of the precise annotation for ClassVar AST._field_types

The current annotation is broad: dict[str, Any].

Details

typeshed/stdlib/ast.pyi

Lines 31 to 38 in 8f5a80e

class AST:
if sys.version_info >= (3, 10):
__match_args__ = ()
_attributes: ClassVar[tuple[str, ...]]
_fields: ClassVar[tuple[str, ...]]
if sys.version_info >= (3, 13):
_field_types: ClassVar[dict[str, Any]]

If ast.Constant and/or ast.MatchSingleton, without "stdlib/ast.pyi", trumps everything

(.venv) C:\apps\astToolFactory>py
Python 3.13.4 (tags/v3.13.4:8a526ec, Jun  3 2025, 17:46:04) [MSC v.1943 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ast
>>> ast.Constant._field_types
{'value': <class 'object'>, 'kind': str | None}
>>> ast.MatchSingleton._field_types
{'value': <class 'object'>}

Answer: dict[str, Any].
QED; close issue.

My code underlying the following analysis

You can play along at home!

Details

from ast import *  # pyright: ignore[reportWildcardImportFromLibrary] # noqa: F403
from ast import AST, Constant
from builtins import Ellipsis as ellipsis
from collections import defaultdict
from itertools import chain
from types import EllipsisType, GenericAlias
from typing import Literal
import ast
import typing
import typing_extensions

# NOTE Settings
includeDeprecated = False  # Set to `True` to include deprecated AST classes.
replace_class_object = True  # Set to `True` to replace `class` `object` with "stdlib/ast.pyi" types.
replaceLiteralBoolean = True  # Set to `True` to replace `Literal[True, False]` with `bool`
use_ConstantValueTypeAlias = True  # Set to `True` to replace `str | bytes | bool | int | float | complex | None | ellipsis` with the TypeAlias from "stdlib/ast.pyi".

listASTClasses: list[type[AST]] = []
for astClass in sorted([AST, *chain(*map(lambda c: c.__subclasses__(), [AST, Constant, *AST.__subclasses__()]))], key=lambda c: c.__name__):
    if not issubclass(astClass, AST):
        continue
    if not includeDeprecated:
        if bool(astClass.__doc__ and 'Deprecated' in astClass.__doc__):
            continue
    listASTClasses.append(astClass)

listASTClassesWith_field_types: list[type[AST]] = []
for astClass in listASTClasses:
    try:
        astClass._field_types
    except AttributeError:
        continue
    listASTClassesWith_field_types.append(astClass)

_ConstantValue: typing_extensions.TypeAlias = str | bytes | bool | int | float | complex | None | EllipsisType

dictionaryAnnotations: dict[str, list[tuple[str, str]]] = defaultdict(list)
for astClass in listASTClassesWith_field_types:
    className: str = astClass.__name__

    for field in astClass._field_types:
        annotation_field_type = None
        annotationSherpa = astClass._field_types[field]
        if not isinstance(annotationSherpa, GenericAlias):
            try:
                annotation_field_type = annotationSherpa.__name__
                if annotation_field_type == 'object' and replace_class_object:
                    if className == Constant.__name__ and field == 'value':
                        annotation_field_type = _ConstantValue
                        if use_ConstantValueTypeAlias:
                            annotation_field_type = '_ConstantValue'
                    if className == ast.MatchSingleton.__name__ and field == 'value':
                        annotation_field_type = Literal[True, False]
                        if replaceLiteralBoolean:
                            annotation_field_type = bool.__name__
            except Exception:
                pass
        if not annotation_field_type:
            annotation_field_type = str(annotationSherpa)

        dictionaryAnnotations[str(annotation_field_type)].append((className, field))

# START Embarrassing, string parsing, semantically vacant code for which I don't have the health to improve.
setTypesAsStr: set[str] = set()
for annotation_field_type in dictionaryAnnotations.keys():
    listTypesAsStr: list[str] = annotation_field_type.split('|')
    setTypesAsStr.update([typeAsStr.strip().replace('ast.', '') for typeAsStr in listTypesAsStr])

if use_ConstantValueTypeAlias:
    setConstantValueTypeAlias: set[str] = {typeAsStr.strip().replace('ast.', '') for typeAsStr in str(_ConstantValue).split('|')}
    setTypesAsStr = setTypesAsStr - setConstantValueTypeAlias

setTypesSansSubclassesAsStr: set[str] = set()

setOfClassesAST: set[type] = set()
setOfListsAST: set[type] = set()
for typeAsStr in setTypesAsStr:
    if typeAsStr.startswith('list'):
        typeTarget: type = eval(typeAsStr.replace('list[', '').replace(']', ''))
        if issubclass(typeTarget, AST):
            setOfListsAST.add(typeTarget)
        else:
            setTypesSansSubclassesAsStr.add(typeAsStr)
    else:
        typeTarget: type = eval(typeAsStr)
        if isinstance(typeTarget, type) and issubclass(typeTarget, AST):
            setOfClassesAST.add(typeTarget)
        else:
            setTypesSansSubclassesAsStr.add(typeAsStr)

setOfClassesASTCompacted: set[type] = {classTarget for classTarget in setOfClassesAST if not any(issubclass(classTarget, otherClass) and classTarget is not otherClass for otherClass in setOfClassesAST)}
setOfListsASTCompacted: set[type] = {classTarget for classTarget in setOfListsAST if not any(issubclass(classTarget, otherClass) and classTarget is not otherClass for otherClass in setOfListsAST)}

print(f"{setOfClassesAST == setOfClassesASTCompacted = }")
print(f"{setOfListsAST == setOfListsASTCompacted = }")


setOfClassesAST.add(ast.AST)
setOfListsAST.add(AST)
setOfClassesASTCompacted: set[type] = {classTarget for classTarget in setOfClassesAST if not any(issubclass(classTarget, otherClass) and classTarget is not otherClass for otherClass in setOfClassesAST)}
setOfListsASTCompacted: set[type] = {classTarget for classTarget in setOfListsAST if not any(issubclass(classTarget, otherClass) and classTarget is not otherClass for otherClass in setOfListsAST)}

listASTisAST: list[str] = (
    sorted(
        [classTarget.__name__ for classTarget in setOfClassesASTCompacted]
        + [f"list[{classTarget.__name__}]" for classTarget in setOfListsASTCompacted]
        + list(setTypesSansSubclassesAsStr),
        key=lambda string: string.lower()
    )
)

setOfClassesASTExpanded: set[type] = set(chain.from_iterable(
    [classTarget] + list(classTarget.__subclasses__()) for classTarget in setOfClassesAST
))
setOfListsASTExpanded: set[type] = set(chain.from_iterable(
    [classTarget] + list(classTarget.__subclasses__()) for classTarget in setOfListsAST
))

setOfClassesASTOverInclusive: set[type] = set(listASTClasses) - setOfClassesASTExpanded
setOfListsASTOverInclusive: set[type] = set(listASTClasses) - setOfListsASTExpanded

listOverInclusive: list[str] = (
    sorted(
        [classTarget.__name__ for classTarget in setOfClassesASTOverInclusive] +
        [f"list[{classTarget.__name__}]" for classTarget in setOfListsASTOverInclusive],
        key=lambda string: string.lower()
    )
)

# END Embarrassing, string parsing, semantically vacant code for which I don't have the health to improve.

# This is BYOp: Bring Your Own print().

Baseline

Details

includeDeprecated = False  # Set to `True` to include deprecated AST classes.
Annotation list[(Class, attribute)]
arguments [('AsyncFunctionDef', 'args'), ('FunctionDef', 'args'), ('Lambda', 'args')]
ast.arg | None [('arguments', 'vararg'), ('arguments', 'kwarg')]
ast.expr | None [('AnnAssign', 'value'), ('Assert', 'msg'), ('AsyncFunctionDef', 'returns'), ('ExceptHandler', 'type'), ('FormattedValue', 'format_spec'), ('FunctionDef', 'returns'), ('ParamSpec', 'default_value'), ('Raise', 'exc'), ('Raise', 'cause'), ('Return', 'value'), ('Slice', 'lower'), ('Slice', 'upper'), ('Slice', 'step'), ('TypeVar', 'bound'), ('TypeVar', 'default_value'), ('TypeVarTuple', 'default_value'), ('Yield', 'value'), ('arg', 'annotation'), ('match_case', 'guard'), ('withitem', 'optional_vars')]
ast.pattern | None [('MatchAs', 'pattern')]
boolop [('BoolOp', 'op')]
expr [('AnnAssign', 'target'), ('AnnAssign', 'annotation'), ('Assert', 'test'), ('Assign', 'value'), ('AsyncFor', 'target'), ('AsyncFor', 'iter'), ('Attribute', 'value'), ('AugAssign', 'target'), ('AugAssign', 'value'), ('Await', 'value'), ('BinOp', 'left'), ('BinOp', 'right'), ('Call', 'func'), ('Compare', 'left'), ('DictComp', 'key'), ('DictComp', 'value'), ('Expr', 'value'), ('Expression', 'body'), ('For', 'target'), ('For', 'iter'), ('FormattedValue', 'value'), ('FunctionType', 'returns'), ('GeneratorExp', 'elt'), ('If', 'test'), ('IfExp', 'test'), ('IfExp', 'body'), ('IfExp', 'orelse'), ('Lambda', 'body'), ('ListComp', 'elt'), ('Match', 'subject'), ('MatchClass', 'cls'), ('MatchValue', 'value'), ('NamedExpr', 'target'), ('NamedExpr', 'value'), ('SetComp', 'elt'), ('Starred', 'value'), ('Subscript', 'value'), ('Subscript', 'slice'), ('TypeAlias', 'name'), ('TypeAlias', 'value'), ('UnaryOp', 'operand'), ('While', 'test'), ('YieldFrom', 'value'), ('comprehension', 'target'), ('comprehension', 'iter'), ('keyword', 'value'), ('withitem', 'context_expr')]
expr_context [('Attribute', 'ctx'), ('List', 'ctx'), ('Name', 'ctx'), ('Starred', 'ctx'), ('Subscript', 'ctx'), ('Tuple', 'ctx')]
int [('AnnAssign', 'simple'), ('FormattedValue', 'conversion'), ('TypeIgnore', 'lineno'), ('comprehension', 'is_async')]
int | None [('ImportFrom', 'level')]
list[ast.alias] [('Import', 'names'), ('ImportFrom', 'names')]
list[ast.arg] [('arguments', 'posonlyargs'), ('arguments', 'args'), ('arguments', 'kwonlyargs')]
list[ast.cmpop] [('Compare', 'ops')]
list[ast.comprehension] [('DictComp', 'generators'), ('GeneratorExp', 'generators'), ('ListComp', 'generators'), ('SetComp', 'generators')]
list[ast.excepthandler] [('Try', 'handlers'), ('TryStar', 'handlers')]
list[ast.expr] [('Assign', 'targets'), ('AsyncFunctionDef', 'decorator_list'), ('BoolOp', 'values'), ('Call', 'args'), ('ClassDef', 'bases'), ('ClassDef', 'decorator_list'), ('Compare', 'comparators'), ('Delete', 'targets'), ('Dict', 'keys'), ('Dict', 'values'), ('FunctionDef', 'decorator_list'), ('FunctionType', 'argtypes'), ('JoinedStr', 'values'), ('List', 'elts'), ('MatchMapping', 'keys'), ('Set', 'elts'), ('Tuple', 'elts'), ('arguments', 'kw_defaults'), ('arguments', 'defaults'), ('comprehension', 'ifs')]
list[ast.keyword] [('Call', 'keywords'), ('ClassDef', 'keywords')]
list[ast.match_case] [('Match', 'cases')]
list[ast.pattern] [('MatchClass', 'patterns'), ('MatchClass', 'kwd_patterns'), ('MatchMapping', 'patterns'), ('MatchOr', 'patterns'), ('MatchSequence', 'patterns')]
list[ast.stmt] [('AsyncFor', 'body'), ('AsyncFor', 'orelse'), ('AsyncFunctionDef', 'body'), ('AsyncWith', 'body'), ('ClassDef', 'body'), ('ExceptHandler', 'body'), ('For', 'body'), ('For', 'orelse'), ('FunctionDef', 'body'), ('If', 'body'), ('If', 'orelse'), ('Interactive', 'body'), ('Module', 'body'), ('Try', 'body'), ('Try', 'orelse'), ('Try', 'finalbody'), ('TryStar', 'body'), ('TryStar', 'orelse'), ('TryStar', 'finalbody'), ('While', 'body'), ('While', 'orelse'), ('With', 'body'), ('match_case', 'body')]
list[ast.type_ignore] [('Module', 'type_ignores')]
list[ast.type_param] [('AsyncFunctionDef', 'type_params'), ('ClassDef', 'type_params'), ('FunctionDef', 'type_params'), ('TypeAlias', 'type_params')]
list[ast.withitem] [('AsyncWith', 'items'), ('With', 'items')]
list[str] [('Global', 'names'), ('MatchClass', 'kwd_attrs'), ('Nonlocal', 'names')]
operator [('AugAssign', 'op'), ('BinOp', 'op')]
pattern [('match_case', 'pattern')]
str [('AsyncFunctionDef', 'name'), ('Attribute', 'attr'), ('ClassDef', 'name'), ('FunctionDef', 'name'), ('Name', 'id'), ('ParamSpec', 'name'), ('TypeIgnore', 'tag'), ('TypeVar', 'name'), ('TypeVarTuple', 'name'), ('alias', 'name'), ('arg', 'arg')]
str | None [('Assign', 'type_comment'), ('AsyncFor', 'type_comment'), ('AsyncFunctionDef', 'type_comment'), ('AsyncWith', 'type_comment'), ('Constant', 'kind'), ('ExceptHandler', 'name'), ('For', 'type_comment'), ('FunctionDef', 'type_comment'), ('ImportFrom', 'module'), ('MatchAs', 'name'), ('MatchMapping', 'rest'), ('MatchStar', 'name'), ('With', 'type_comment'), ('alias', 'asname'), ('arg', 'type_comment'), ('keyword', 'arg')]
str | bytes | bool | int | float | complex | None | ellipsis [('Constant', 'value')]
typing.Literal[True, False] [('MatchSingleton', 'value')]
unaryop [('UnaryOp', 'op')]

Possible replacements for ast.Constant.value and ast.MatchSingleton.value

I don't know if this is haram, but I think these are valid substitutions.

  • Replace Literal[True, False] with bool
  • Replace str | bytes | bool | int | float | complex | None | ellipsis with a typing.TypeAlias
Type list[(Class, attribute)]
bool [('MatchSingleton', 'value')]
_ConstantValue [('Constant', 'value')]

If each unique type must be listed

dict[str, arg | arguments | bool | boolop | bytes | complex | ellipsis | expr | expr_context | float | int
    | list[alias] | list[arg] | list[cmpop] | list[comprehension] | list[excepthandler] | list[expr] | list[keyword]
    | list[match_case] | list[pattern] | list[stmt] | list[str] | list[type_ignore] | list[type_param] | list[withitem]
    | operator | pattern | str | unaryop | None]

With a TypeAlias

dict[str, _ConstantValue | arg | arguments | boolop | expr | expr_context 
    | list[alias] | list[arg] | list[cmpop] | list[comprehension] | list[excepthandler] | list[expr] | list[keyword]
    | list[match_case] | list[pattern] | list[stmt] | list[str] | list[type_ignore] | list[type_param] | list[withitem]
    | operator | pattern | unaryop]

Fold subclasses into their parent classes if the parent class is present

No change!

Details

(.venv) C:\apps\astToolFactory>Z0Z_field_types.py                                                                       
setOfClassesAST == setOfClassesASTCompacted = True
setOfListsAST == setOfListsASTCompacted = True

Arrogantly fold ast.AST subclasses into ast.AST even though it is not present

dict[str, bool | bytes | complex | ellipsis | float | int | list[str] | str | AST | list[AST] | None]

With a TypeAlias

dict[str, _ConstantValue | list[str] | AST | list[AST]]

ast.AST is extremely over-inclusive: 92 classes and lists of class

Details

alias | AnnAssign | Assert | Assign | AST | AsyncFor | AsyncFunctionDef | AsyncWith | AugAssign | Break | ClassDef
| cmpop | comprehension | Continue | Delete | Eq | ExceptHandler | excepthandler | Expr | Expression | For
| FunctionDef | FunctionType | Global | Gt | GtE | If | Import | ImportFrom | In | Interactive | Is | IsNot | keyword
| list[Add] | list[And] | list[arguments] | list[AST] | list[BitAnd] | list[BitOr] | list[BitXor] | list[boolop]
| list[Del] | list[Div] | list[expr_context] | list[Expression] | list[FloorDiv] | list[FunctionType]
| list[Interactive] | list[Invert] | list[Load] | list[LShift] | list[MatMult] | list[mod] | list[Mod] | list[Module]
| list[Mult] | list[Not] | list[operator] | list[Or] | list[Pow] | list[RShift] | list[Store] | list[Sub] | list[UAdd]
| list[unaryop] | list[USub] | Lt | LtE | Match | match_case | mod | Module | Nonlocal | NotEq | NotIn | ParamSpec
| Pass | Raise | Return | stmt | Try | TryStar | type_ignore | type_param | TypeAlias | TypeIgnore | TypeVar
| TypeVarTuple | While | With | withitem

🛑 Summary 🛑

The Brahman annotation

dict[str, Any]

All true names

dict[str, None | arg | arguments | bool | boolop | bytes | complex | ellipsis | expr | expr_context | float | int 
    | list[alias] | list[arg] | list[cmpop] | list[comprehension] | list[excepthandler] | list[expr] | list[keyword]
    | list[match_case] | list[pattern] | list[stmt] | list[str] | list[type_ignore] | list[type_param] | list[withitem]
    | operator | pattern | str | typing.Literal[True, False] | unaryop]

Like, literally all identifiers

dict[str, None | arg | arguments | bool | boolop | bytes | complex | ellipsis | expr | expr_context | float | int
    | list[alias] | list[arg] | list[cmpop] | list[comprehension] | list[excepthandler] | list[expr] | list[keyword]
    | list[match_case] | list[pattern] | list[stmt] | list[str] | list[type_ignore] | list[type_param] | list[withitem]
    | operator | pattern | str | unaryop]

typing.TypeAlias

dict[str, _ConstantValue | arg | arguments | boolop | expr | expr_context | list[alias] | list[arg] | list[cmpop]
    | list[comprehension] | list[excepthandler] | list[expr] | list[keyword] | list[match_case] | list[pattern]
    | list[stmt] | list[str] | list[type_ignore] | list[type_param] | list[withitem] | operator | pattern | unaryop]

"All AST look the same"

dict[str, AST | bool | bytes | complex | ellipsis | float | int | list[AST] | list[str] | None | str
    | typing.Literal[True, False]]

"No, like, literally the same"

dict[str, AST | bool | bytes | complex | ellipsis | float | int | list[AST] | list[str] | None | str]

Peak hubris

dict[str, _ConstantValue | AST | list[AST] | list[str]]

Annex: ._field_type for every ast.AST subclass

Code

Details

from ast import *
from itertools import chain

ASTfield_types:dict[str, str | dict[str, str]] = {}
for astClass in [C for C in [AST,*chain(*map(lambda c:c.__subclasses__(), [AST,Constant,*AST.__subclasses__()]))] if issubclass(C,AST)]:
    try:
        field_types = {k:str(v).replace("<class '",'').replace("'>",'') for k,v in astClass._field_types.items()}
    except Exception as ERRORmessage:
        field_types = ERRORmessage.__class__.__name__
    ASTfield_types[astClass.__name__] = field_types

print(*ASTfield_types.items(), sep='\n')

print

Details

('AST', 'AttributeError')
('mod', 'AttributeError')
('stmt', 'AttributeError')
('expr', 'AttributeError')
('expr_context', 'AttributeError')
('boolop', 'AttributeError')
('operator', 'AttributeError')
('unaryop', 'AttributeError')
('cmpop', 'AttributeError')
('comprehension', {'target': 'ast.expr', 'iter': 'ast.expr', 'ifs': 'list[ast.expr]', 'is_async': 'int'})
('excepthandler', 'AttributeError')
('arguments', {'posonlyargs': 'list[ast.arg]', 'args': 'list[ast.arg]', 'vararg': 'ast.arg | None', 'kwonlyargs': 'list[ast.arg]', 'kw_defaults': 'list[ast.expr]', 'kwarg': 'ast.arg | None', 'defaults': 'list[ast.expr]'})
('arg', {'arg': 'str', 'annotation': 'ast.expr | None', 'type_comment': 'str | None'})
('keyword', {'arg': 'str | None', 'value': 'ast.expr'})
('alias', {'name': 'str', 'asname': 'str | None'})
('withitem', {'context_expr': 'ast.expr', 'optional_vars': 'ast.expr | None'})
('match_case', {'pattern': 'ast.pattern', 'guard': 'ast.expr | None', 'body': 'list[ast.stmt]'})
('pattern', 'AttributeError')
('type_ignore', 'AttributeError')
('type_param', 'AttributeError')
('slice', 'AttributeError')
('Num', {'value': 'object', 'kind': 'str | None'})
('Str', {'value': 'object', 'kind': 'str | None'})
('Bytes', {'value': 'object', 'kind': 'str | None'})
('NameConstant', {'value': 'object', 'kind': 'str | None'})
('Ellipsis', {'value': 'object', 'kind': 'str | None'})
('Module', {'body': 'list[ast.stmt]', 'type_ignores': 'list[ast.type_ignore]'})
('Interactive', {'body': 'list[ast.stmt]'})
('Expression', {'body': 'ast.expr'})
('FunctionType', {'argtypes': 'list[ast.expr]', 'returns': 'ast.expr'})
('Suite', 'AttributeError')
('FunctionDef', {'name': 'str', 'args': 'ast.arguments', 'body': 'list[ast.stmt]', 'decorator_list': 'list[ast.expr]', 'returns': 'ast.expr | None', 'type_comment': 'str | None', 'type_params': 'list[ast.type_param]'})
('AsyncFunctionDef', {'name': 'str', 'args': 'ast.arguments', 'body': 'list[ast.stmt]', 'decorator_list': 'list[ast.expr]', 'returns': 'ast.expr | None', 'type_comment': 'str | None', 'type_params': 'list[ast.type_param]'})
('ClassDef', {'name': 'str', 'bases': 'list[ast.expr]', 'keywords': 'list[ast.keyword]', 'body': 'list[ast.stmt]', 'decorator_list': 'list[ast.expr]', 'type_params': 'list[ast.type_param]'})
('Return', {'value': 'ast.expr | None'})
('Delete', {'targets': 'list[ast.expr]'})
('Assign', {'targets': 'list[ast.expr]', 'value': 'ast.expr', 'type_comment': 'str | None'})
('TypeAlias', {'name': 'ast.expr', 'type_params': 'list[ast.type_param]', 'value': 'ast.expr'})
('AugAssign', {'target': 'ast.expr', 'op': 'ast.operator', 'value': 'ast.expr'})
('AnnAssign', {'target': 'ast.expr', 'annotation': 'ast.expr', 'value': 'ast.expr | None', 'simple': 'int'})
('For', {'target': 'ast.expr', 'iter': 'ast.expr', 'body': 'list[ast.stmt]', 'orelse': 'list[ast.stmt]', 'type_comment': 'str | None'})
('AsyncFor', {'target': 'ast.expr', 'iter': 'ast.expr', 'body': 'list[ast.stmt]', 'orelse': 'list[ast.stmt]', 'type_comment': 'str | None'})
('While', {'test': 'ast.expr', 'body': 'list[ast.stmt]', 'orelse': 'list[ast.stmt]'})
('If', {'test': 'ast.expr', 'body': 'list[ast.stmt]', 'orelse': 'list[ast.stmt]'})
('With', {'items': 'list[ast.withitem]', 'body': 'list[ast.stmt]', 'type_comment': 'str | None'})
('AsyncWith', {'items': 'list[ast.withitem]', 'body': 'list[ast.stmt]', 'type_comment': 'str | None'})
('Match', {'subject': 'ast.expr', 'cases': 'list[ast.match_case]'})
('Raise', {'exc': 'ast.expr | None', 'cause': 'ast.expr | None'})
('Try', {'body': 'list[ast.stmt]', 'handlers': 'list[ast.excepthandler]', 'orelse': 'list[ast.stmt]', 'finalbody': 'list[ast.stmt]'})
('TryStar', {'body': 'list[ast.stmt]', 'handlers': 'list[ast.excepthandler]', 'orelse': 'list[ast.stmt]', 'finalbody': 'list[ast.stmt]'})
('Assert', {'test': 'ast.expr', 'msg': 'ast.expr | None'})
('Import', {'names': 'list[ast.alias]'})
('ImportFrom', {'module': 'str | None', 'names': 'list[ast.alias]', 'level': 'int | None'})
('Global', {'names': 'list[str]'})
('Nonlocal', {'names': 'list[str]'})
('Expr', {'value': 'ast.expr'})
('Pass', {})
('Break', {})
('Continue', {})
('BoolOp', {'op': 'ast.boolop', 'values': 'list[ast.expr]'})
('NamedExpr', {'target': 'ast.expr', 'value': 'ast.expr'})
('BinOp', {'left': 'ast.expr', 'op': 'ast.operator', 'right': 'ast.expr'})
('UnaryOp', {'op': 'ast.unaryop', 'operand': 'ast.expr'})
('Lambda', {'args': 'ast.arguments', 'body': 'ast.expr'})
('IfExp', {'test': 'ast.expr', 'body': 'ast.expr', 'orelse': 'ast.expr'})
('Dict', {'keys': 'list[ast.expr]', 'values': 'list[ast.expr]'})
('Set', {'elts': 'list[ast.expr]'})
('ListComp', {'elt': 'ast.expr', 'generators': 'list[ast.comprehension]'})
('SetComp', {'elt': 'ast.expr', 'generators': 'list[ast.comprehension]'})
('DictComp', {'key': 'ast.expr', 'value': 'ast.expr', 'generators': 'list[ast.comprehension]'})
('GeneratorExp', {'elt': 'ast.expr', 'generators': 'list[ast.comprehension]'})
('Await', {'value': 'ast.expr'})
('Yield', {'value': 'ast.expr | None'})
('YieldFrom', {'value': 'ast.expr'})
('Compare', {'left': 'ast.expr', 'ops': 'list[ast.cmpop]', 'comparators': 'list[ast.expr]'})
('Call', {'func': 'ast.expr', 'args': 'list[ast.expr]', 'keywords': 'list[ast.keyword]'})
('FormattedValue', {'value': 'ast.expr', 'conversion': 'int', 'format_spec': 'ast.expr | None'})
('JoinedStr', {'values': 'list[ast.expr]'})
('Constant', {'value': 'object', 'kind': 'str | None'})
('Attribute', {'value': 'ast.expr', 'attr': 'str', 'ctx': 'ast.expr_context'})
('Subscript', {'value': 'ast.expr', 'slice': 'ast.expr', 'ctx': 'ast.expr_context'})
('Starred', {'value': 'ast.expr', 'ctx': 'ast.expr_context'})
('Name', {'id': 'str', 'ctx': 'ast.expr_context'})
('List', {'elts': 'list[ast.expr]', 'ctx': 'ast.expr_context'})
('Tuple', {'elts': 'list[ast.expr]', 'ctx': 'ast.expr_context'})
('Slice', {'lower': 'ast.expr | None', 'upper': 'ast.expr | None', 'step': 'ast.expr | None'})
('Load', {})
('Store', {})
('Del', {})
('AugLoad', 'AttributeError')
('AugStore', 'AttributeError')
('Param', 'AttributeError')
('And', {})
('Or', {})
('Add', {})
('Sub', {})
('Mult', {})
('MatMult', {})
('Div', {})
('Mod', {})
('Pow', {})
('LShift', {})
('RShift', {})
('BitOr', {})
('BitXor', {})
('BitAnd', {})
('FloorDiv', {})
('Invert', {})
('Not', {})
('UAdd', {})
('USub', {})
('Eq', {})
('NotEq', {})
('Lt', {})
('LtE', {})
('Gt', {})
('GtE', {})
('Is', {})
('IsNot', {})
('In', {})
('NotIn', {})
('ExceptHandler', {'type': 'ast.expr | None', 'name': 'str | None', 'body': 'list[ast.stmt]'})
('MatchValue', {'value': 'ast.expr'})
('MatchSingleton', {'value': 'object'})
('MatchSequence', {'patterns': 'list[ast.pattern]'})
('MatchMapping', {'keys': 'list[ast.expr]', 'patterns': 'list[ast.pattern]', 'rest': 'str | None'})
('MatchClass', {'cls': 'ast.expr', 'patterns': 'list[ast.pattern]', 'kwd_attrs': 'list[str]', 'kwd_patterns': 'list[ast.pattern]'})
('MatchStar', {'name': 'str | None'})
('MatchAs', {'pattern': 'ast.pattern | None', 'name': 'str | None'})
('MatchOr', {'patterns': 'list[ast.pattern]'})
('TypeIgnore', {'lineno': 'int', 'tag': 'str'})
('TypeVar', {'name': 'str', 'bound': 'ast.expr | None', 'default_value': 'ast.expr | None'})
('ParamSpec', {'name': 'str', 'default_value': 'ast.expr | None'})
('TypeVarTuple', {'name': 'str', 'default_value': 'ast.expr | None'})
('Index', 'AttributeError')
('ExtSlice', 'AttributeError')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant