Skip to content

Conventions for variance terminology #257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion python2/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
17 changes: 9 additions & 8 deletions python2/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.:

Expand All @@ -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:
Expand Down Expand Up @@ -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__:
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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::
Expand Down
2 changes: 1 addition & 1 deletion src/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
17 changes: 9 additions & 8 deletions src/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.:

Expand All @@ -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:
Expand Down Expand Up @@ -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__:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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::
Expand Down