Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem matching dictionaries into Protocols #13898

Closed
dmoisset opened this issue Oct 14, 2022 · 3 comments
Closed

Problem matching dictionaries into Protocols #13898

dmoisset opened this issue Oct 14, 2022 · 3 comments
Labels
bug mypy got something wrong

Comments

@dmoisset
Copy link
Contributor

I'm exploring capturing in a Protocol some of the readable interface of a Mapping where values have different types for keys (like a lightweight Mapping version of TypedDict. I expected the snippet below to work but it doesn't:

To Reproduce

from typing import Literal, Protocol, overload


class MyMap(Protocol):

    @overload
    def __getitem__(self, key: Literal["a"]) -> int: ...
    @overload
    def __getitem__(self, key: Literal["b"]) -> str: ...    

m: MyMap = {"a": 1, "b": "hello"}

Expected Behavior

I expected the assignment above to type check properly, given that the dictionary object used satisfies the constraints given in the MyMap protocol.

Actual Behavior

map.py:11: error: Incompatible types in assignment (expression has type "Dict[Literal['a'], int]", variable has type "MyMap")
map.py:11: note: Following member(s) of "Dict[Literal['a'], int]" have conflicts:
map.py:11: note:     Expected:
map.py:11: note:         @overload
map.py:11: note:         def __getitem__(self, Literal['a']) -> int
map.py:11: note:         @overload
map.py:11: note:         def __getitem__(self, Literal['b']) -> str
map.py:11: note:     Got:
map.py:11: note:         def __getitem__(self, Literal['a']) -> int
map.py:11: error: Dict entry 1 has incompatible type "Literal['b']": "str"; expected "Literal['a']": "int"
Found 2 errors in 1 file (checked 1 source file)

Even if my expected behaviour is incorrect, there's something wrong with this error message, where it says that expression has type "Dict[Literal['a'], int]" (which clearly isn't the type of the expression)

Your Environment

  • Mypy version used: 0.982 (compiled: yes)
  • Mypy command-line flags: just the filename
  • Python version used: 3.10.8
@dmoisset dmoisset added the bug mypy got something wrong label Oct 14, 2022
@tmke8
Copy link
Contributor

tmke8 commented Oct 15, 2022

Doesn't address your protocol problem but there was discussion about a read-only TypedDict on the mailing list: https://mail.python.org/archives/list/typing-sig@python.org/thread/6FR6RKNUZU4UY6B6RXC2H4IAHKBU3UKV/

@dmoisset
Copy link
Contributor Author

Doesn't address your protocol problem but there was discussion about a read-only TypedDict on the mailing list: https://mail.python.org/archives/list/typing-sig@python.org/thread/6FR6RKNUZU4UY6B6RXC2H4IAHKBU3UKV/

I'm aware of that thread (I wrote this code after looking at it trying to explore alternative implementations); still I think the issue goes beyond the original problem

@erictraut
Copy link

The signature of dict.__getitem__ doesn't match the protocol in your code sample, so mypy correct reports a type compatibility error. I think mypy is doing the right thing here. Recommend closing.

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Aug 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

4 participants