Skip to content

str not detected as Hashable #8293

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

Closed
corynezin opened this issue Jan 16, 2020 · 4 comments
Closed

str not detected as Hashable #8293

corynezin opened this issue Jan 16, 2020 · 4 comments

Comments

@corynezin
Copy link

This is probably a duplicate of #1746 - but I don't see a resolution

  • Are you reporting a bug, or opening a feature request?
  • Not sure if it's a bug or intended
  • Please insert below the code you are checking with mypy,
    or a mock-up repro if the source is private. We would appreciate
    if you try to simplify your case to a minimal repro.
from typing import Hashable, Dict

def foo(d: Dict[Hashable, int]):
  ...

d: Dict[str, int] = {'a': 1}
foo(d)
  • What is the actual behavior/output?
    test.py:7: error: Argument 1 to "foo" has incompatible type "Dict[str, int]"; expected "Dict[Hashable, int]"
  • What is the behavior/output you expect?
    Success: no issues found in 1 source file
  • What are the versions of mypy and Python you are using?
    Do you see the same issue after installing mypy from Git master?
    mypy 0.761
  • What are the mypy flags you are using? (For example --strict-optional)
    None
  • If mypy crashed with a traceback, please paste
    the full traceback below.

(You can freely edit this text, please remove all the lines
you believe are unnecessary.)

@JelleZijlstra
Copy link
Member

This due to invariance; see https://mypy.readthedocs.io/en/latest/common_issues.html#invariance-vs-covariance. (Although Hashable is generally not very well-supported anyway.)

@jamesmcm
Copy link

Is there a solution to this aside from just ignoring the type check though?

Every str should be Hashable, so why doesn't this work?

@Michael0x2a
Copy link
Collaborator

@jamesmcm -- mypy is reporting a legitimate issue with the above code. Basically, it would be legal for foo to do d[1] = 2 since ints are hashable, but that would end up breaking the caller since the keys are now no longer strings.

The docs linked above discuss this problem and some workarounds. The quickest one for the above example would be to switch to having foo accept a Mapping[Hashable, int], which is a read-only version of a dict, which in turn means the key type is allowed to be covariant instead of invariant.

Or to rephrase, having the data structure be read-only/disallowing foo from mutating the input means we can be more permissive about what we can pass in.

@JelleZijlstra
Copy link
Member

@Michael0x2a Mapping is actually also invariant in the key type, see https://github.com/python/typeshed/blob/master/stdlib/3/typing.pyi#L400.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants