Description
Currently, the type hint for Mapping.values()
requires implementors of the Mapping
interface to return a ValuesView
:
class Mapping(_Collection[_KT], Generic[_KT, _VT_co]):
...
def values(self) -> ValuesView[_VT_co]: ...
But ValuesView
is too narrow. For example, an ABC for a BidirectionalMapping
interface which extends the Mapping
interface should be able to declare that the values()
method returns an AbstractSet
(since the values of a bidirectional mapping actually make up a set), as I need to do in my bidict
library. Note that an AbstractSet
satisfies the contract of a ValuesView
. But currently declaring this causes the mypy error, Return type "AbstractSet[VT]" of "values" incompatible with return type "ValuesView[VT]" in supertype "Mapping"
.
(Notice that the type hints for Mapping.keys()
and Mapping.items()
return AbstractSet
rather than KeysView
and ItemsView
, respectively, because even KeysView
and ItemsView
would have been too narrow there. In other words, those type hints are abstract enough. Only the type hint for values()
is not abstract enough.)
It looks like one way to fix this would be to declare that Mapping.values()
must return a Collection[VT]
rather than a ValuesView[VT]
. Since AbstractSet
is a subtype of Collection
, then BidirectionalMapping.values()
(and other implementors) could return an AbstractSet[VT]
(or any other subtype) and still satisfy the contract for Mapping.values()
.
Does that make sense, or would some other fix be better here?