[Python-Dev] dict __contains__ raises TypeError on unhashable input

Ethan Furman ethan at stoneleaf.us
Sun Jul 21 03:37:57 CEST 2013


On 07/20/2013 03:21 AM, Ronald Oussoren wrote:
>
> On 20 Jul, 2013, at 1:47, Ethan Furman <ethan at stoneleaf.us> wrote:
>
>> While working on issue #18508 I stumbled across this:
>>
>> Traceback (most recent call last):
>> ...
>>   File "/usr/local/lib/python3.4/enum.py", line 417, in __new__
>>     if value in cls._value2member_map:
>> TypeError: unhashable type: 'list'
>>
>> I'll wrap it in a try-except block, but I must admit I was surprised the answer wasn't False.  After all, if the input is unhashable then obviously it's not in the dict; furthermore, if I were to compare the number 5 with a set() I would get False, not a TypeMismatch error, and dict keys are basically done by equality, the hash is just (?) a speed-up.
>
> Not quite, there are some objects that compare equal without both of them being hashable:
>
>>>> frozenset([1,2]) == set([1,2])
> True
>>>> dct = { frozenset([1,2]): 1 }
>>>> frozenset([1,2]) in dct
> True
>>>> set([1,2]) in dct
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: unhashable type: 'set'
>
> It would be strange if the last test would return False instead of raising an error.

Yeah, that would be unfortunate.

Okay, I can see dict.__contains__ and friends raising a TypeError, but 
what about dict.keys() ?  In 2.x it returned a list, in 3.x it returns a 
dict_keys, and dict_keys also raises an error instead of returning False.

--
~Ethan~


More information about the Python-Dev mailing list