From 25cb6e4ab491a5474d79e9825987d9a78c01ce2e Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 5 Sep 2016 12:57:37 -0700 Subject: [PATCH] Make Mapping covariant. (#512) * Make Mapping covariant. Fixes #510. This requires a `# type: ignore` on `__getitem__` and `get` because mypy complains about covariant parameters. FWIW typing.py needs to be changed too. (It was covariant in the value but invariant in the key -- typeshed was invariant in both.) * Delete outdated comment. * Backpeddle a bit -- Mapping key type should not be covariant. --- stdlib/2.7/typing.pyi | 18 +++++++++++------- stdlib/3/typing.pyi | 16 +++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/stdlib/2.7/typing.pyi b/stdlib/2.7/typing.pyi index 5e0906e0d..e8aa48a6f 100644 --- a/stdlib/2.7/typing.pyi +++ b/stdlib/2.7/typing.pyi @@ -176,17 +176,21 @@ class ValuesView(MappingView, Iterable[_VT_co], Generic[_VT_co]): def __contains__(self, o: object) -> bool: ... def __iter__(self) -> Iterator[_VT_co]: ... -class Mapping(Sized, Iterable[_KT], Container[_KT], Generic[_KT, _VT]): +class Mapping(Sized, Iterable[_KT], Container[_KT], Generic[_KT, _VT_co]): + # TODO: We wish the key type could also be covariant, but that doesn't work, + # see discussion in https://github.com/python/typing/pull/273. @abstractmethod - def __getitem__(self, k: _KT) -> _VT: ... + def __getitem__(self, k: _KT) -> _VT_co: + ... # Mixin methods - def get(self, k: _KT, default: _VT = ...) -> _VT: ... + def get(self, k: _KT, default: _VT_co = ...) -> _VT_co: # type: ignore + ... def keys(self) -> list[_KT]: ... - def values(self) -> list[_VT]: ... - def items(self) -> list[Tuple[_KT, _VT]]: ... + def values(self) -> list[_VT_co]: ... + def items(self) -> list[Tuple[_KT, _VT_co]]: ... def iterkeys(self) -> Iterator[_KT]: ... - def itervalues(self) -> Iterator[_VT]: ... - def iteritems(self) -> Iterator[Tuple[_KT, _VT]]: ... + def itervalues(self) -> Iterator[_VT_co]: ... + def iteritems(self) -> Iterator[Tuple[_KT, _VT_co]]: ... def __contains__(self, o: object) -> bool: ... class MutableMapping(Mapping[_KT, _VT], Generic[_KT, _VT]): diff --git a/stdlib/3/typing.pyi b/stdlib/3/typing.pyi index 438d2648b..d5389962a 100644 --- a/stdlib/3/typing.pyi +++ b/stdlib/3/typing.pyi @@ -226,16 +226,18 @@ class ValuesView(MappingView, Iterable[_VT_co], Generic[_VT_co]): # TODO: ContextManager (only if contextlib.AbstractContextManager exists) -class Mapping(Iterable[_KT], Container[_KT], Sized, Generic[_KT, _VT]): - # TODO: Value type should be covariant, but currently we can't give a good signature for - # get if this is the case. +class Mapping(Iterable[_KT], Container[_KT], Sized, Generic[_KT, _VT_co]): + # TODO: We wish the key type could also be covariant, but that doesn't work, + # see discussion in https://github.com/python/typing/pull/273. @abstractmethod - def __getitem__(self, k: _KT) -> _VT: ... + def __getitem__(self, k: _KT) -> _VT_co: + ... # Mixin methods - def get(self, k: _KT, default: _VT = ...) -> _VT: ... - def items(self) -> AbstractSet[Tuple[_KT, _VT]]: ... + def get(self, k: _KT, default: _VT_co = ...) -> _VT_co: # type: ignore + ... + def items(self) -> AbstractSet[Tuple[_KT, _VT_co]]: ... def keys(self) -> AbstractSet[_KT]: ... - def values(self) -> ValuesView[_VT]: ... + def values(self) -> ValuesView[_VT_co]: ... def __contains__(self, o: object) -> bool: ... class MutableMapping(Mapping[_KT, _VT], Generic[_KT, _VT]):