-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Update documentation of SymbolTableNode #4080
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2233,19 +2233,53 @@ def __getattribute__(self, attr: str) -> None: | |
|
||
|
||
class SymbolTableNode: | ||
"""Description of a name binding in a symbol table. | ||
|
||
These are only used as values in module (global), function (local) | ||
and class symbol tables (see SymbolTable). The name that is bound is | ||
the key in SymbolTable. | ||
|
||
Symbol tables don't contain direct references to AST nodes primarily | ||
because there can be multiple symbol table references to a single | ||
AST node (due to imports and aliases), and different references can | ||
behave differently. This class describes the unique properties of | ||
each reference. | ||
|
||
The most fundamental attributes are 'kind' and 'node'. The 'node' | ||
attribute defines the AST node that the name refers to. | ||
|
||
For many bindings, including those targeting variables, functions | ||
and classes, the kind is one of LDEF, GDEF or MDEF, depending on the | ||
scope of the definition. These three kinds can usually be used | ||
interchangeably and the difference between local, global and class | ||
scopes is mostly descriptive, with no semantic significance. | ||
However, some tools that consume mypy ASTs may care about these so | ||
they should be correct. | ||
|
||
A few definitions get special kinds, including type variables (TVAR), | ||
imported modules and module aliases (MODULE_REF), and type aliases | ||
(TYPE_ALIAS). | ||
|
||
Type aliases are very special and have additional attributes that | ||
are only used for them ('type_override', 'alias_tvars' at least). | ||
""" | ||
# TODO: This is a mess. Refactor! | ||
# TODO: Describe how type aliases work. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type aliases are quite complicated (due to several corner cases). I tried to make some simplifications recently. It seems to me that we can introduce a dedicated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that's what I was thinking about. I'd also like to deprecate the special handling of module references and other special node kinds so that we could remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it makes sense to open an issue to track this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created #4082. |
||
|
||
# Kind of node. Possible values: | ||
# - LDEF: local definition (of any kind) | ||
# - LDEF: local definition | ||
# - GDEF: global (module-level) definition | ||
# - MDEF: class member definition | ||
# - TVAR: TypeVar(...) definition | ||
# - TVAR: TypeVar(...) definition in any scope | ||
# - MODULE_REF: reference to a module | ||
# - TYPE_ALIAS: type alias | ||
# - UNBOUND_IMPORTED: temporary kind for imported names | ||
# - UNBOUND_IMPORTED: temporary kind for imported names (we don't know the final kind yet) | ||
kind = None # type: int | ||
# AST node of definition (FuncDef/Var/TypeInfo/Decorator/TypeVarExpr, | ||
# AST node of definition (among others, this can be FuncDef/Var/TypeInfo/TypeVarExpr/MypyFile, | ||
# or None for a bound type variable). | ||
node = None # type: Optional[SymbolNode] | ||
# If this not None, override the type of the 'node' attribute. | ||
# If this not None, override the type of the 'node' attribute. This is only used for | ||
# type aliases. | ||
type_override = None # type: Optional[mypy.types.Type] | ||
# For generic aliases this stores the (qualified) names of type variables. | ||
# (For example see testGenericAliasWithTypeVarsFromDifferentModules.) | ||
|
@@ -2258,7 +2292,9 @@ class SymbolTableNode: | |
# For deserialized MODULE_REF nodes, the referenced module name; | ||
# for other nodes, optionally the name of the referenced object. | ||
cross_ref = None # type: Optional[str] | ||
# Was this node created by normalіze_type_alias? | ||
# Used to distinguish between 'typing.List' and 'builtins.list'. This is | ||
# True when the former has been normalized to the latter, and it allow us | ||
# to reject 'list[str]' and similar. | ||
normalized = False # type: bool | ||
# Was this defined by assignment to self attribute? | ||
implicit = False # type: bool | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it will be helpful to note that this is a bit similar to how CPython symbol tables work. There are no
.node
, only.kind
(and there are more than three kinds however). These kinds are used to emit correct lookup opcodes, so that the right.node
will be found by the interpreter at runtime (I know this comparison is vague).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm talking about CPython implementation details might not be helpful, as many readers likely aren't familiar with them.