Skip to content

Make it possible to make Mapping covariant #738

Closed

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.

Activity

  1. gvanrossum commented on Apr 17, 2017

    @gvanrossum
    Member

    I'm closing this. It's old, Mapping is currently covariant in the value (as requested in the first sentence of the first message above), and the signature of get() has changed so that you now get a more reasonable error:

    error: Argument 1 to "append" of "list" has incompatible type "int"; expected "str"
    
    from typing import *
    d = {}  # type: Dict[int, List[str]]
    a = d.get(1, [])
    reveal_type(a)  # Revealed type is 'builtins.list[builtins.str]'
    a.append(2)  # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "str"

    We're still debating what to do about the key (currently invariant) in #1114.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions