4

Consider the following code:

#!/usr/bin/env python3.7

from typing import NamedTuple, Set

class Person(NamedTuple):
    name: str
    fred: Set[str]


p = Person("Phil", set())
print(p)

my_dict = {}
my_dict[p] = 10


print(my_dict)

which produces this error

Traceback (most recent call last):
  File "./temp.py", line 14, in <module>
    my_dict[p] = 10
TypeError: unhashable type: 'set'

In this case, it's sample code, and I have simplified it lots, so its quite easy to see where the error comes from. typed.NamedTuple obviousl calculates its hash based on all of its instances variables and one of them is a set. When I discovered this, however, it was painful to track down.

So, my question is, why is the error message showing this? Should it not be TypeError: unhashable type: 'Person'. And why is the traceback not coming from the bowels of python somewhere where the error actually is.

1
  • Well, that is the error that is being produced in the bowels of Python, it is trying to hash a set object. Commented Mar 28, 2019 at 16:12

1 Answer 1

1

NamedTuple is based on the tuple class. See collections.namedtuple()

The hash of a tuple is the combined hash of all the elements. See tupleobject.c

Since set is unhashable it is not possible to hash a tuple or NamedTuple containing a set.

And since the hashing of a set is implemented in C you don't see the traceback

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, I see that. I think the HashNotImplemented call is happening too deep. It should be reporting either the outer object type, or the both ("Person is not hashable, because it contains a set which is not hashable").

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.