Skip to content

Mapping.values() return type is too narrow #4435

Closed
@jab

Description

@jab

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions