diff --git a/pep-0484.txt b/pep-0484.txt index b15fe3b05db..7bea81d254c 100644 --- a/pep-0484.txt +++ b/pep-0484.txt @@ -288,7 +288,7 @@ elements. Example:: def notify_by_email(employees: Set[Employee], overrides: Mapping[str, str]) -> None: ... -Generics can be parametrized by using a new factory available in +Generics can be parameterized by using a new factory available in ``typing`` called ``TypeVar``. Example:: from typing import Sequence, TypeVar @@ -306,10 +306,11 @@ variable (it should not be used as part of a larger expression). The argument to ``TypeVar()`` must be a string equal to the variable name to which it is assigned. Type variables must not be redefined. -``TypeVar`` supports constraining parametric types to a fixed set of -possible types. For example, we can define a type variable that ranges -over just ``str`` and ``bytes``. By default, a type variable ranges -over all possible types. Example of constraining a type variable:: +``TypeVar`` supports constraining parametric types to a fixed set of possible +types (note: those types cannot be parametrized by type variables). For +example, we can define a type variable that ranges over just ``str`` and +``bytes``. By default, a type variable ranges over all possible types. +Example of constraining a type variable:: from typing import TypeVar @@ -583,6 +584,7 @@ argument(s) is substituted. Otherwise, ``Any`` is assumed. Example:: class Node(Generic[T]): def __init__(self, label: T = None) -> None: ... + x = None # Type: T x = Node('') # Inferred type is Node[str] y = Node(0) # Inferred type is Node[int] @@ -610,6 +612,21 @@ the runtime class of the objects created by instantiating them doesn't record the distinction. This behavior is called "type erasure"; it is common practice in languages with generics (e.g. Java, TypeScript). +Using generic classes (parameterized or not) to access attributes will result +in type check failure. Outside the class definition body, a class attribute +cannot be assigned, and can only be looked up by accessing it through the +class instance that does not have same-named instance attribute:: + + # (continued from previous example) + Node[int].x = 1 # Error + Node[int].x # Error + Node.x = 1 # Error + Node.x # Error + type(p).x # Error + p.x # Ok (evaluates to None) + Node[int]().x # Ok (evaluates to None) + p.x = 1 # Ok, but assigning to instance attribute + Generic versions of abstract collections like ``Mapping`` or ``Sequence`` and generic versions of built-in classes -- ``List``, ``Dict``, ``Set``, and ``FrozenSet`` -- cannot be instantiated. However, concrete user-defined @@ -701,11 +718,11 @@ classes without a metaclass conflict. Type variables with an upper bound ---------------------------------- -A type variable may specify an upper bound using ``bound=``. -This means that an actual type substituted (explicitly or implicitly) -for the type variable must be a subtype of the boundary type. A -common example is the definition of a Comparable type that works well -enough to catch the most common errors:: +A type variable may specify an upper bound using ``bound=`` (note: + itself cannot be parametrized by type variables). This means that an +actual type substituted (explicitly or implicitly) for the type variable must +be a subtype of the boundary type. A common example is the definition of a +``Comparable`` type that works well enough to catch the most common errors:: from typing import TypeVar @@ -1186,9 +1203,13 @@ concrete class object, e.g. in the above example:: new_non_team_user(ProUser) # OK new_non_team_user(TeamUser) # Disallowed by type checker -``Type[Any]`` is also supported (see below for its meaning). However, -other special constructs like ``Tuple`` or ``Callable`` are not -allowed. +``Type[Any]`` is also supported (see below for its meaning). + +``Type[T]`` where ``T`` is a type variable is allowed when annotating the +first argument of a class method (see the relevant section). + +Any other special constructs like ``Tuple`` or ``Callable`` are not allowed +as an argument to ``Type``. There are some concerns with this feature: for example when ``new_user()`` calls ``user_class()`` this implies that all subclasses @@ -2439,7 +2460,7 @@ Copyright This document has been placed in the public domain. - + .. Local Variables: mode: indented-text