[Python-Dev] Unhashable objects and __contains__()

Georg Brandl g.brandl at gmx.net
Sun Jun 4 00:52:02 CEST 2006

Collin Winter wrote:
> 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?

It would certainly give me an uneasy feeling if a command-line switch
caused such a change in semantics.


More information about the Python-Dev mailing list