Strange Behavior with Old-Style classes and implicit __contains__
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Wed Apr 11 23:32:32 EDT 2007
En Wed, 11 Apr 2007 20:37:35 -0300, <rconradharris at gmail.com> escribió:
> First, we create an instance of an Old-Style class without defining a
> __contains__ but instead define a __getitem__ method in which we raise
> KeyError. Next we repeatedly use the 'in' operator to test to see
> whether something, a string, an int, etc is an attribute of this new
> instance.
>
> Here's the strange part: The first test will return False as if the
> __getitem__ was never called. The next test will raise a KeyError as
> we'd expect. The test after that will again return False. This goes on
> ad infinitum.
>
> In Code:
> Python 2.5 (r25:51908, Jan 21 2007, 03:10:25)
> [GCC 3.4.6 20060404 (Red Hat 3.4.6-3)] on linux2
> Type "help", "copyright", "credits" or "license" for more
> information.
> >>> class Foo:
> ... def __getitem__(self, key):
> ... raise KeyError
> ...
> >>> foo = Foo()
> >>> "asdf" in foo
> False
> >>> "asdf" in foo
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "<stdin>", line 3, in __getitem__
> KeyError
First I want to say that __getitem__ should raise IndexError, not
KeyError, to indicate "not found" - just to make clear the observed
behavior. (Using IndexError, you always get False, as expected).
Python 2.4 and 2.3 never return False, always showing the KeyError
exception, also as expected.
>>>> foo = Foo()
>>>> "asdf" in foo
> False
>>>> 1 in set([1,2,3]) <---- So the prior KeyError from another class
>>>> is interacting and producing bad output
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "<stdin>", line 3, in __getitem__
> KeyError
I have a displayhook installed, and it also were interfering with the
results; it appears that the next __getitem__ call after the KeyError was
raised (wherever it is called) "sees" the previous exception.
You should file a bug at http://sourceforge.net/bugs/?group_id=5470
--
Gabriel Genellina
More information about the Python-list
mailing list