@@ -466,6 +466,8 @@ for the type variable must be a subclass of the boundary type. A
466466common example is the definition of a Comparable type that works well
467467enough to catch the most common errors::
468468
469+ from typing import TypeVar
470+
469471 class Comparable(metaclass=ABCMeta):
470472 @abstractmethod
471473 def __lt__(self, other: Any) -> bool: ...
@@ -495,6 +497,83 @@ upper bound just requires that the actual type is a subclass of the
495497boundary type.
496498
497499
500+ Covariance and contravariance
501+ -----------------------------
502+
503+ Consider a class ``Employee`` with a subclass ``Manager``. Now
504+ suppose we have a function with an argument annotated with
505+ ``List[Employee]``. Should we be allowed to call this function with a
506+ variable of type ``List[Manager]`` as its argument? Many people would
507+ answer "yes, of course" without even considering the consequences.
508+ But unless we know more about the function, a type checker should
509+ reject such a call: the function might append an ``Employee`` instance
510+ to the list, which would violate the variable's type in the caller.
511+
512+ It turns out such an argument acts _contravariantly_, whereas the
513+ intuitive answer (which is correct in case the function doesn't mutate
514+ its argument!) requires the argument to act _covariantly_. A longer
515+ introduction to these concepts can be found on Wikipedia
516+ [wiki-variance]_; here we just show how to control a type checker's
517+ behavior.
518+
519+ By default type variables are considered _invariant_, which means that
520+ arguments for arguments annotated with types like ``List[Employee]``
521+ must exactly match the type annotation -- no subclasses or
522+ superclasses of the type parameter (in this example ``Employee``) are
523+ allowed.
524+
525+ To facilitate the declaration of container types where covariant type
526+ checking is acceptable, a type variable can be declared using
527+ ``covariant=True``. For the (rare) case where contravariant behavior
528+ is desirable, pass ``contravariant=True``. At most one of these may
529+ be passed.
530+
531+ A typical example involves defining an immutable container class::
532+
533+ from typing import TypeVar
534+
535+ T = TypeVar('T', covariant=True)
536+
537+ class ImmutableList(Generic[T]):
538+ def append(self, T): ...
539+ ...
540+
541+ class Employee: ...
542+
543+ class Manager(Employee): ...
544+
545+ def dump_employees(emps: ImmutableList[Employee]) -> None: ...
546+
547+ mgrs = ... # type: ImmutableList[Mananger]
548+ mgrs.append(Manager())
549+
550+ dump_employees(mgrs) # OK
551+
552+ The immutable collection classes in ``typing`` are all defined using a
553+ covariant type variable (e.g. ``Mapping`` and ``Sequence``). The
554+ mutable collection classes (e.g. ``MutableMapping`` and
555+ ``MutableSequence``) are defined using regular invariant type
556+ variables. The one example of a contravariant type variable is the
557+ ``Generator`` type, which is contravariant in the ``send()`` argument
558+ type (see below).
559+
560+ Note: variance affects type parameters for generic types -- it does
561+ not affect regular parameters. For example, the following example is
562+ fine::
563+
564+ from typing import TypeVar
565+
566+ class Employee: ...
567+
568+ class Manager(Employee): ...
569+
570+ E = TypeVar('E', bound=Employee) # Invariant
571+
572+ def dump_employee(e: E) -> None: ...
573+
574+ dump_employee(Manager()) # OK
575+
576+
498577The numeric tower
499578-----------------
500579
@@ -1039,7 +1118,10 @@ the abstract collection types defined below, e.g. ``Mapping``,
10391118The ``typing`` module defines the ``Generator`` type for return values
10401119of generator functions. It is a subtype of ``Iterable`` and it has
10411120additional type variables for the type accepted by the ``send()``
1042- method and the return type of the generator:
1121+ method (which is contravariant -- a generator that accepts sending it
1122+ ``Employee`` instance is valid in a context where a generator is
1123+ required that accepts sending it ``Manager`` instances) and the return
1124+ type of the generator:
10431125
10441126* Generator, used as ``Generator[yield_type, send_type, return_type]``
10451127
@@ -1437,6 +1519,12 @@ References
14371519.. [mypy]
14381520 http://mypy-lang.org
14391521
1522+ .. [gvr-artima]
1523+ http://www.artima.com/weblogs/viewpost.jsp?thread=85551
1524+
1525+ .. [wiki-variance]
1526+ http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29
1527+
14401528.. [typeshed]
14411529 https://github.com/JukkaL/typeshed/
14421530
@@ -1446,9 +1534,6 @@ References
14461534.. [pylint]
14471535 http://www.pylint.org
14481536
1449- .. [gvr-artima]
1450- http://www.artima.com/weblogs/viewpost.jsp?thread=85551
1451-
14521537.. [roberge]
14531538 http://aroberge.blogspot.com/2015/01/type-hinting-in-python-focus-on.html
14541539
0 commit comments