class documentation

class TypeAlias(SymbolNode): (source)

View In Hierarchy

A symbol node representing a type alias.

Type alias is a static concept, in contrast to variables with types like Type[...]. Namely:

  • type aliases
    • can be used in type context (annotations)
    • cannot be re-assigned
  • variables with type Type[...]
    • cannot be used in type context
    • but can be re-assigned

An alias can be defined only by an assignment to a name (not any other lvalues).

Such assignment defines an alias by default. To define a variable, an explicit Type[...] annotation is required. As an exception, at non-global scope non-subscripted rvalue creates a variable even without an annotation. This exception exists to accommodate the common use case of class-valued attributes. See SemanticAnalyzerPass2.check_and_set_up_type_alias for details.

Aliases can be generic. Currently, mypy uses unbound type variables for generic aliases and identifies them by name. Essentially, type aliases work as macros that expand textually. The definition and expansion rules are following:

1. An alias targeting a generic class without explicit variables act as the given class (this doesn't apply to Tuple and Callable, which are not proper classes but special type constructors):

A = List AA = List[Any]

x: A # same as List[Any] x: A[int] # same as List[int]

x: AA # same as List[Any] x: AA[int] # Error!

C = Callable # Same as Callable[..., Any] T = Tuple # Same as Tuple[Any, ...]

2. An alias using explicit type variables in its rvalue expects replacements (type arguments) for these variables. If missing, they are treated as Any, like for other generics:

B = List[Tuple[T, T]]

x: B # same as List[Tuple[Any, Any]] x: B[int] # same as List[Tuple[int, int]]

def f(x: B[T]) -> T: ... # without T, Any would be used here

3. An alias can be defined using another aliases. In the definition rvalue the Any substitution doesn't happen for top level unsubscripted generic classes:

A = List B = A # here A is expanded to List, _not_ List[Any],

# to match the Python runtime behaviour

x: B[int] # same as List[int] C = List[A] # this expands to List[List[Any]]

AA = List[T] D = AA # here AA expands to List[Any] x: D[int] # Error!

Note: the fact that we support aliases like A = List means that the target type will be initially an instance type with wrong number of type arguments. Such instances are all fixed in the third pass of semantic analyzis. We therefore store the difference between List and List[Any] rvalues (targets) using the no_args flag. See also TypeAliasExpr.no_args.

Meaning of other fields:

target: The target type. For generic aliases contains unbound type variables
as nested types.
_fullname: Qualified name of this type alias. This is used in particular
to track fine grained dependencies from aliases.

alias_tvars: Names of unbound type variables used to define this alias. normalized: Used to distinguish between A = List, and A = list. Both

are internally stored using builtins.list (because typing.List is itself an alias), while the second cannot be subscripted because of Python runtime limitation.

line and column: Line an column on the original alias definition. eager: If True, immediately expand alias when referred to (useful for aliases

within functions that can't be looked up from the symbol table)
Class Method deserialize Undocumented
Method __init__ Undocumented
Method accept Undocumented
Method serialize Undocumented
Class Variable __slots__ Undocumented
Instance Variable alias​_tvars Undocumented
Instance Variable eager Undocumented
Instance Variable no​_args Undocumented
Instance Variable normalized Undocumented
Instance Variable target Undocumented
Property fullname Undocumented
Property name Undocumented
Instance Variable _fullname Undocumented
Instance Variable _is​_recursive Undocumented

Inherited from Node (via SymbolNode):

Method __str__ Undocumented

Inherited from Context (via SymbolNode, Node):

Method get​_column Don't use. Use x.column.
Method get​_line Don't use. Use x.line.
Method set​_line If target is a node, pull line (and column) information into this node. If column is specified, this will override any column information coming from a node.
Instance Variable column Undocumented
Instance Variable end​_line Undocumented
Instance Variable line Undocumented
@classmethod
def deserialize(cls, data): (source)

Undocumented

Parameters
data:JsonDictUndocumented
Returns
TypeAliasUndocumented
def __init__(self, target, fullname, line, column, *, alias_tvars=None, no_args=False, normalized=False, eager=False): (source)

Undocumented

Parameters
target:mypy.types.TypeUndocumented
fullname:strUndocumented
line:intUndocumented
column:intUndocumented
alias​_tvars:Optional[List[str]]Undocumented
no​_args:boolUndocumented
normalized:boolUndocumented
eager:boolUndocumented
def accept(self, visitor): (source)

Undocumented

Parameters
visitor:NodeVisitor[T]Undocumented
Returns
TUndocumented
def serialize(self): (source)

Undocumented

Returns
JsonDictUndocumented
__slots__: tuple[str, ...] = (source)

Undocumented

alias_tvars = (source)

Undocumented

eager = (source)

Undocumented

no_args = (source)

Undocumented

normalized = (source)

Undocumented

target = (source)

Undocumented

@property
fullname: str = (source)

Undocumented

@property
name: str = (source)

Undocumented

_fullname = (source)

Undocumented

_is_recursive: Optional[bool] = (source)

Undocumented