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