module documentation
(source)

The semantic analyzer.

Bind names to definitions and do various other simple consistency checks. Populate symbol tables. The semantic analyzer also detects special forms which reuse generic syntax such as NamedTuple and cast(). Multiple analysis iterations may be needed to analyze forward references and import cycles. Each iteration "fills in" additional bindings and references until everything has been bound.

For example, consider this program:

x = 1 y = x

Here semantic analysis would detect that the assignment 'x = 1' defines a new variable, the type of which is to be inferred (in a later pass; type inference or type checking is not part of semantic analysis). Also, it would bind both references to 'x' to the same module-level variable (Var) node. The second assignment would also be analyzed, and the type of 'y' marked as being inferred.

Semantic analysis of types is implemented in typeanal.py.

See semanal_main.py for the top-level logic.

Some important properties:

  • After semantic analysis is complete, no PlaceholderNode and PlaceholderType instances should remain. During semantic analysis, if we encounter one of these, the current target should be deferred.
  • A TypeInfo is only created once we know certain basic information about a type, such as the MRO, existence of a Tuple base class (e.g., for named tuples), and whether we have a TypedDict. We use a temporary PlaceholderNode node in the symbol table if some such information is missing.
  • For assignments, we only add a non-placeholder symbol table entry once we know the sort of thing being defined (variable, NamedTuple, type alias, etc.).
  • Every part of the analysis step must support multiple iterations over the same AST nodes, and each iteration must be able to fill in arbitrary things that were missing or incomplete in previous iterations.
  • Changes performed by the analysis need to be reversible, since mypy daemon strips and reuses existing ASTs (to improve performance and/or reduce memory use).
Class ​Has​Placeholders Undocumented
Class ​Make​Any​Non​Explicit Undocumented
Class ​Semantic​Analyzer Semantically analyze parsed mypy files.
Function apply​_semantic​_analyzer​_patches Call patch callbacks in the right order.
Function dummy​_context Undocumented
Function find​_duplicate If the list has duplicates, return one of the duplicates.
Function has​_placeholder Check if a type contains any placeholder types (recursively).
Function is​_same​_symbol Undocumented
Function is​_same​_var​_from​_getattr Do n1 and n2 refer to the same Var derived from module-level __getattr__?
Function is​_valid​_replacement Can symbol table node replace an existing one?
Function make​_any​_non​_explicit Replace all Any types within in with Any that has attribute 'explicit' set to False
Function names​_modified​_by​_assignment Return all unqualified (short) names assigned to in an assignment statement.
Function names​_modified​_in​_lvalue Return all NameExpr assignment targets in an Lvalue.
Function refers​_to​_class​_or​_function Does semantically analyzed node refer to a class?
Function refers​_to​_fullname Is node a name or member expression with the given full name?
Function remove​_imported​_names​_from​_symtable Remove all imported names from the symbol table of a module.
Function replace​_implicit​_first​_type Undocumented
Constant CORE​_BUILTIN​_CLASSES Undocumented
Constant FUTURE​_IMPORTS Undocumented
Constant T Undocumented
def apply_semantic_analyzer_patches(patches): (source)

Call patch callbacks in the right order.

This should happen after semantic analyzer pass 3.

Parameters
patches:List[Tuple[int, Callable[[], None]]]Undocumented
def dummy_context(): (source)

Undocumented

Returns
ContextUndocumented
def find_duplicate(list): (source)

If the list has duplicates, return one of the duplicates.

Otherwise, return None.

Parameters
list:List[T]Undocumented
Returns
Optional[T]Undocumented
def has_placeholder(typ): (source)
Check if a type contains any placeholder types (recursively).
Parameters
typ:TypeUndocumented
Returns
boolUndocumented
def is_same_symbol(a, b): (source)

Undocumented

Parameters
a:Optional[SymbolNode]Undocumented
b:Optional[SymbolNode]Undocumented
Returns
boolUndocumented
def is_same_var_from_getattr(n1, n2): (source)
Do n1 and n2 refer to the same Var derived from module-level __getattr__?
Parameters
n1:Optional[SymbolNode]Undocumented
n2:Optional[SymbolNode]Undocumented
Returns
boolUndocumented
def is_valid_replacement(old, new): (source)

Can symbol table node replace an existing one?

These are the only valid cases:

  1. Placeholder gets replaced with a non-placeholder
  2. Placeholder that isn't known to become type replaced with a placeholder that can become a type
Parameters
old:SymbolTableNodeUndocumented
new:SymbolTableNodeUndocumented
Returns
boolUndocumented
def make_any_non_explicit(t): (source)
Replace all Any types within in with Any that has attribute 'explicit' set to False
Parameters
t:TypeUndocumented
Returns
TypeUndocumented
def names_modified_by_assignment(s): (source)
Return all unqualified (short) names assigned to in an assignment statement.
Parameters
s:AssignmentStmtUndocumented
Returns
List[NameExpr]Undocumented
def names_modified_in_lvalue(lvalue): (source)
Return all NameExpr assignment targets in an Lvalue.
Parameters
lvalue:LvalueUndocumented
Returns
List[NameExpr]Undocumented
def refers_to_class_or_function(node): (source)
Does semantically analyzed node refer to a class?
Parameters
node:ExpressionUndocumented
Returns
boolUndocumented
def refers_to_fullname(node, fullname): (source)
Is node a name or member expression with the given full name?
Parameters
node:ExpressionUndocumented
fullname:strUndocumented
Returns
boolUndocumented
def remove_imported_names_from_symtable(names, module): (source)
Remove all imported names from the symbol table of a module.
Parameters
names:SymbolTableUndocumented
module:strUndocumented
def replace_implicit_first_type(sig, new): (source)

Undocumented

Parameters
sig:FunctionLikeUndocumented
new:TypeUndocumented
Returns
FunctionLikeUndocumented
CORE_BUILTIN_CLASSES: list[str] = (source)

Undocumented

Value
['object', 'bool', 'function']
FUTURE_IMPORTS: dict[str, str] = (source)

Undocumented

Value
{'__future__.nested_scopes': 'nested_scopes',
 '__future__.generators': 'generators',
 '__future__.division': 'division',
 '__future__.absolute_import': 'absolute_import',
 '__future__.with_statement': 'with_statement',
 '__future__.print_function': 'print_function',
 '__future__.unicode_literals': 'unicode_literals',
...

Undocumented

Value
TypeVar('T')