Skip to content

Make it possible to make Mapping covariant #738

Closed
@JukkaL

Description

@JukkaL

Mapping should be covariant with respect to value, but get() makes it impossible for now, so it's actually invariant.

I'd like to have a signature like this for get (we can't use _VT_co in an argument type, as it's covariant):

    def get(self, k: _KT, default: _T = ...) -> Union[_VT_co, _T]: pass

However, code like this is currently a problem if we use the above signature:

from typing import Dict, List

d = {}  # type: Dict[int, List[str]]
a = d.get(1, [])
a.append(2)  # Error, type of a is Union[List[str], List[None]], which is bad!

Maybe type inference should use the union return type for the type context of the second argument, since the argument type is an item in the union. This is a little arbitrary but seems safe, and it would fix the above issue, which is probably fairly common. There are probably a bunch of edge cases that need to be considered, but the general idea seems like it could work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions