[Python-Dev] Unhashable objects and __contains__()

Collin Winter collinw at gmail.com
Sun Jun 4 00:25:07 CEST 2006

I recently submitted a patch that would optimise "in (5, 6, 7)" (ie,
"in" ops on constant tuples) to "in frozenset([5, 6, 7])". Raymond
Hettinger rejected (rightly) the patch since it's not semantically
consistent. Quoth:

>> Sorry, this enticing idea has already been explored and
>> rejected.  This is issue is that the transformation is not
>> semanatically neutral.  Currently, writing "{} in (1,2,3)"
>> returns False, but after the transformation would raise an
>> exception, "TypeError: dict objects are unhashable".

My question is this: maybe set/frozenset.__contains__ (as well as
dict.__contains__, etc) should catch such TypeErrors and convert them
to a return value of False? It makes sense that "{} in frozenset([(1,
2, 3])" should be False, since unhashable objects (like {}) clearly
can't be part of the set/dict/whatever.

I am, however, a bit unsure as to how __contains__() would be sure it
was only catching the "this object can't be hash()ed" TypeErrors, as
opposed to other TypeErrors that might legimately arise from a call to
some __hash__() method.

Idea: what if Python's -O option caused PySequence_Contains() to
convert all errors into False return values?

Collin Winter

More information about the Python-Dev mailing list