Skip to content

Add a covariant Mapping-like type #5

Closed as not planned
Closed as not planned
@harahu

Description

@harahu

What

I want a new protocol added to typing or typing_extensions, expressing the aspects of Mapping that are covariant with regards to the key type. That is, the Mapping type, but without the __getitem__ and get methods.

Something along the lines of:

class CovariantMappingLike(Protocol[KT_co, VT_co]):
    # A better name for this protocol might be needed
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def keys(self) -> KeysView[KT_co]: ...
    def items(self) -> ItemsView[KT_co, VT_co]: ...
    def values(self) -> ValuesView[VT_co]: ...

Why

Mappings are often, in practice, treated in ways that make them covariant with regards to key. A specific example is laid out in a comment of mine found here: python/typing#445 (comment)

The Mapping type, however, cannot be covariant w. regards to key, as it also implements methods that don't allow for it (__getitem__ and get) to be covariant.

This leaves me unable to express, in a simple and idiomatic way, that I intend to use a Mapping in a way that respects covariance.

Being able to write:

def foo(mapping: CovariantMappingLike[Hashable, Hashable]) -> int:
    ...

would allow me to express what I'm after. It would allow me to express: "Give me a mapping, but I promise to not be looking up keys on it."

This, again, makes it possible to have narrower key types for my Mapping objects, as I can pass a narrowly typed Mapping to foo, without casting:

my_map: Dict[Literal["foo", "bar", "baz"], str] = {}

# I want this to be fine
foo(my_mapping)

I was prompted by @srittau to create this issue in python/typing#445 (comment)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions