Glossary

This section defines a few terms that may be used elsewhere in the specification.

annotation expression

An expression that is valid to use within an annotation. This is usually a type expression, sometimes with additional type qualifiers. See “Type and annotation expression” for details.

assignable

If a type B is “assignable to” a type A, a type checker should not error on the assignment x: A = b, where b is some expression whose type is B. Similarly for function calls and returns: f(b) where def f(x: A): ... and return b inside def f(...) -> A: ... are both valid (not type errors) if and only if B is assignable to A. In this case A is “assignable from” B. For fully static types, “assignable to” is equivalent to “subtype of” and “assignable from” is equivalent to “supertype of”. For gradual types, a type B is assignable to a type A if there exist fully static materializations A' and B' of A and B, respectively, such that B' is a subtype of A'. See Type system concepts.

consistent

Two fully static types are “consistent with” each other if they are equivalent. Two gradual types are “consistent with” each other if they could materialize to the same type. See Type system concepts. If two types are consistent, they are both assignable to and from each other.

consistent subtype

“Consistent subtype” is synonymous with “assignable to” (and “consistent supertype” is synonymous with “assignable from”). See Type system concepts.

distribution

The packaged file which is used to publish and distribute a release. (PEP 426)

equivalent

Two fully static types A and B are equivalent if A is a subtype of B and B is a subtype of A. This implies that A and B represent the same set of possible runtime objects. Two gradual types A and B are equivalent if all materializations of A are also materializations of B, and all materializations of B are also materializations of A.

fully static type

A type is “fully static” if it does not contain any gradual form. A fully static type represents a set of possible runtime values. Fully static types participate in the subtype relation. See Type system concepts.

gradual form

A gradual form is an element of a type expression which makes the type it is part of not a fully static type, but rather a representation of a set of possible static types. See Type system concepts. The primary gradual form is Any. The ellipsis (...) is a gradual form in some, but not all, contexts. It is a gradual form when used in a Callable type, and when used in tuple[Any, ...] (but not in other tuple types).

gradual type

All types in the Python type system are “gradual”. A gradual type may be a fully static type, or it may be Any, or a type that contains Any or another gradual form. A gradual type does not necessarily represent a single set of possible runtime values; instead it can represent a set of possible static types (a set of possible sets of possible runtime values). Gradual types which are not fully static do not participate in the subtype relation, but they do participate in consistency and assignability. They can be materialized to a more static, or fully static, type. See Type system concepts.

inline

Inline type annotations are annotations that are included in the runtime code using PEP 526 and PEP 3107 syntax (the filename ends in .py).

materialize

A gradual type can be materialized to a more static type (possibly a fully static type) by replacing Any with any other type, or by replacing the in a Callable type with a list of types, or by replacing tuple[Any, ...] with a specific-length tuple type. This materialization relation is key to defining assignability for gradual types. See Type system concepts.

module

A file containing Python runtime code or stubbed type information.

narrow

A fully static type B is narrower than a fully static type A if B is a subtype of A and B is not equivalent to A. This means that B represents a proper subset of the possible objects represented by A. “Type narrowing” is when a type checker infers that a name or expression must have a narrower type at some locations in control flow, due to an assignment or a runtime check of its value.

nominal

A nominal type (e.g. a class name) represents the set of values whose __class__ is that type, or any of its subclasses, transitively. In contrast, see structural types.

package

A directory or directories that namespace Python modules. (Note the distinction between packages and distributions. While most distributions are named after the one package they install, some distributions install multiple packages.)

special form

A special form is an object that has a special meaning within the type system, comparable to a keyword in the language grammar. Examples include Any, Generic, Literal, and TypedDict. Special forms can often but not always be used within type expressions. Special forms can usually be imported from the typing module or equivalently from typing_extensions, but some special forms are placed in other modules.

structural

A structural type (see e.g. Protocols, TypedDict) defines a set of values not by their __class__, but by their properties (e.g. attributes, methods, dictionary key/value types). Callable types are also structural; a callable type is a subtype of another callable type based on their signatures, not a subclass relationship. In contrast, see nominal types.

stub

A file containing only type information, empty of runtime code (the filename ends in .pyi). See Stub files.

subtype

A fully static type B is a subtype of a fully static type A if and only if the set of possible runtime values represented by B is a subset of the set of possible runtime values represented by A. For nominal types (classes), subtyping is defined by inheritance. For structural types, subtyping is defined by a shared set of attributes/methods or keys. Subtype is the inverse of supertype. A type that is not fully static is not a subtype or supertype of any other type, but via materialization can be assignable to another type. See Type system concepts.

supertype

A fully static type A is a supertype of a fully static type B if and only if the set of possible runtime values represented by A is a superset of the set of possible runtime values represented by B. Supertype is the inverse of subtype. See Type system concepts.

type expression

An expression that represents a type. The type system requires the use of type expressions within annotation expression and also in several other contexts. See “Type and annotation expression” for details.

type qualifier

A type qualifier is a special form that qualifies a type expression to form an annotation expression. For example, the type qualifier Final can be used around a type to indicate that the annotated value may not be overridden or modified. This term is also used for other special forms that modify a type, but using a different syntactic context, such as the @final decorator.

wide

A fully static type A is wider than a fully static type B if and only if B is a subtype of A and B is not equivalent to A. This means that A represents a proper superset of the possible values represented by B. See also “narrow”.