diff --git a/python2/test_typing.py b/python2/test_typing.py index 434afdba..2e31d4d0 100644 --- a/python2/test_typing.py +++ b/python2/test_typing.py @@ -827,7 +827,7 @@ def test_covariance_tuple(self): def test_covariance_sequence(self): # Check covariance for Sequence (which is just a generic class - # for this purpose, but using a covariant type variable). + # for this purpose, but using a type variable with covariant=True). self.assertIsSubclass(typing.Sequence[Manager], typing.Sequence[Employee]) self.assertNotIsSubclass(typing.Sequence[Employee], diff --git a/python2/typing.py b/python2/typing.py index 9a96aca2..855f8df7 100644 --- a/python2/typing.py +++ b/python2/typing.py @@ -385,9 +385,10 @@ def longest(x: A, y: A) -> A: and issubclass(bytes, A) are true, and issubclass(int, A) is false. (TODO: Why is this needed? This may change. See #136.) - Type variables may be marked covariant or contravariant by passing - covariant=True or contravariant=True. See PEP 484 for more - details. By default type variables are invariant. + Type variables defined with covariant=True or contravariant=True + can be used do declare covariant or contravariant generic types. + See PEP 484 for more details. By default generic types are invariant + in all type variables. Type variables can be introspected. e.g.: @@ -406,7 +407,7 @@ def __new__(cls, name, *constraints, **kwargs): contravariant = kwargs.get('contravariant', False) self = super(TypeVar, cls).__new__(cls, name, (Final,), {}) if covariant and contravariant: - raise ValueError("Bivariant type variables are not supported.") + raise ValueError("Bivariant types are not supported.") self.__covariant__ = bool(covariant) self.__contravariant__ = bool(contravariant) if constraints and bound is not None: @@ -1055,7 +1056,7 @@ def __subclasscheck__(self, cls): if cls is Any: return True if isinstance(cls, GenericMeta): - # For a class C(Generic[T]) where T is co-variant, + # For a covariant class C(Generic[T]), # C[X] is a subclass of C[Y] iff X is a subclass of Y. origin = self.__origin__ if origin is not None and origin is cls.__origin__: @@ -1389,7 +1390,7 @@ class MutableSet(AbstractSet[T]): __extra__ = collections_abc.MutableSet -# NOTE: Only the value type is covariant. +# NOTE: It is only covariant in the value type. class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co]): __extra__ = collections_abc.Mapping @@ -1523,11 +1524,11 @@ def __new__(cls, *args, **kwds): # Internal type variable used for Type[]. -CT = TypeVar('CT', covariant=True, bound=type) +CT_co = TypeVar('CT_co', covariant=True, bound=type) # This is not a real generic class. Don't use outside annotations. -class Type(type, Generic[CT]): +class Type(type, Generic[CT_co]): """A special construct usable to annotate class objects. For example, suppose we have the following classes:: diff --git a/src/test_typing.py b/src/test_typing.py index a7f8dd50..c1875e4e 100644 --- a/src/test_typing.py +++ b/src/test_typing.py @@ -852,7 +852,7 @@ def test_covariance_tuple(self): def test_covariance_sequence(self): # Check covariance for Sequence (which is just a generic class - # for this purpose, but using a covariant type variable). + # for this purpose, but using a type variable with covariant=True). self.assertIsSubclass(typing.Sequence[Manager], typing.Sequence[Employee]) self.assertNotIsSubclass(typing.Sequence[Employee], diff --git a/src/typing.py b/src/typing.py index 19811352..870293db 100644 --- a/src/typing.py +++ b/src/typing.py @@ -382,9 +382,10 @@ def longest(x: A, y: A) -> A: and issubclass(bytes, A) are true, and issubclass(int, A) is false. (TODO: Why is this needed? This may change. See #136.) - Type variables may be marked covariant or contravariant by passing - covariant=True or contravariant=True. See PEP 484 for more - details. By default type variables are invariant. + Type variables defined with covariant=True or contravariant=True + can be used do declare covariant or contravariant generic types. + See PEP 484 for more details. By default generic types are invariant + in all type variables. Type variables can be introspected. e.g.: @@ -399,7 +400,7 @@ def __new__(cls, name, *constraints, bound=None, covariant=False, contravariant=False): self = super().__new__(cls, name, (Final,), {}, _root=True) if covariant and contravariant: - raise ValueError("Bivariant type variables are not supported.") + raise ValueError("Bivariant types are not supported.") self.__covariant__ = bool(covariant) self.__contravariant__ = bool(contravariant) if constraints and bound is not None: @@ -1038,7 +1039,7 @@ def __subclasscheck__(self, cls): if cls is Any: return True if isinstance(cls, GenericMeta): - # For a class C(Generic[T]) where T is co-variant, + # For a covariant class C(Generic[T]), # C[X] is a subclass of C[Y] iff X is a subclass of Y. origin = self.__origin__ if origin is not None and origin is cls.__origin__: @@ -1440,7 +1441,7 @@ class MutableSet(AbstractSet[T], extra=collections_abc.MutableSet): pass -# NOTE: Only the value type is covariant. +# NOTE: It is only covariant in the value type. class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co], extra=collections_abc.Mapping): pass @@ -1577,11 +1578,11 @@ def __new__(cls, *args, **kwds): # Internal type variable used for Type[]. -CT = TypeVar('CT', covariant=True, bound=type) +CT_co = TypeVar('CT_co', covariant=True, bound=type) # This is not a real generic class. Don't use outside annotations. -class Type(type, Generic[CT], extra=type): +class Type(type, Generic[CT_co], extra=type): """A special construct usable to annotate class objects. For example, suppose we have the following classes::