Skip to content

Collection of Hashable doesn't work properly #6764

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
SLAPaper opened this issue May 5, 2019 · 1 comment
Closed

Collection of Hashable doesn't work properly #6764

SLAPaper opened this issue May 5, 2019 · 1 comment

Comments

@SLAPaper
Copy link

SLAPaper commented May 5, 2019

# test_hashable.py
from typing import List, Set, Hashable

test_int: int = 5
test_hashable: Hashable = test_int

test_list1 = [1, 2, 3]
test_list2: List[Hashable] = test_list1

test_set1: Set[int] = {1, 2, 3}
test_set2: Set[Hashable] = test_set1

def f(key_set: Set[Hashable]) -> None:
    pass

f(test_set1)
> mypy .\test_hashable.py
test_hashable.py:7: error: Incompatible types in assignment (expression has type "List[int]", variable has type "List[Hashable]")
test_hashable.py:10: error: Incompatible types in assignment (expression has type "Set[int]", variable has type "Set[Hashable]")
test_hashable.py:15: error: Argument 1 to "f" has incompatible type "Set[int]"; expected "Set[Hashable]"

> mypy -V
mypy 0.701

> python -V
Python 3.7.3

int itself seems to be recognized as Hashable correctly since #1746, but collections of Hashable seems not accepting collections of int.
Is this behavior expected and I'm doing something wrong? If so, then what type annotaion should I write when I want a collection of dictionary keys?

@JelleZijlstra
Copy link
Member

This is related to invariance; you can read up on this in the docs. Your code is unsafe because something like this could happen:

x: List[int] = [1, 2, 3]
y: List[Hashable] = x
y.append("string")

for element in x:
    print(element + 1)  # blows up because x now contains a string, even though it's a List[int]

You can fix type checking by using covariant container types like Sequence or Iterable instead.

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

2 participants