473,881 Members | 1,545 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Strange Behavior with Old-Style classes and implicit __contains__

A co-worker of mine came across some interesting behavior in the
Python interpreter today and I'm hoping someone more knowledgeable in
Python internals can explain this to me.

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__(sel f, 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
>>"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
According to the language reference, if __contains__ isn't defined for
Old-Style classes and __getitem__ is defined, __getitem__ will be
called. So, how then can False ever be returned?

And to make matters worse, I've set up a situation where Python will
flat-out return incorrect results:

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__(sel f, key):
.... raise KeyError
....
>>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

According to our cursory testing, this funny business doesn't happen
with New-Style Classes or when using PyPy.

If anyone can provide some insight into this, it would be greatly
appreciated.

Thanks,
Rick Harris

Apr 11 '07 #1
5 1518
On Wed, 11 Apr 2007 16:37:35 -0700, rconradharris wrote:
A co-worker of mine came across some interesting behavior in the
Python interpreter today and I'm hoping someone more knowledgeable in
Python internals can explain this to me.

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.
I can confirm that. It looks like __getitem__ is only being called every
second time.

class Parrot:
def __getitem__(sel f, n):
print "Checking index %s..." % n
raise KeyError

def tester(n):
parrot = Parrot()
results = []
for i in range(n):
try:
results.append( i in parrot)
except KeyError:
results.append( "KeyError")
return results

Here are the results under Python 2.5:
>>tester(10)
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
[False, 'KeyError', False, 'KeyError', False,
'KeyError', False, 'KeyError', False, 'KeyError']
And here are the results under Python 2.4.3:
>>tester(10)
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
['KeyError', 'KeyError', 'KeyError', 'KeyError', 'KeyError',
'KeyError', 'KeyError', 'KeyError', 'KeyError', 'KeyError']
Looks like a bug to me.

--
Steven.

Apr 12 '07 #2
En Wed, 11 Apr 2007 20:37:35 -0300, <rc***********@ gmail.comescrib ió:
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__(sel f, 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

Apr 12 '07 #3
On Thu, 12 Apr 2007 00:32:32 -0300, Gabriel Genellina wrote:
First I want to say that __getitem__ should raise IndexError, not
KeyError, to indicate "not found"
How do you know the Original Poster's class was meant to be a sequence
rather than a mapping?

--
Steven.

Apr 12 '07 #4
Steven D'Aprano wrote:
On Wed, 11 Apr 2007 16:37:35 -0700, rconradharris wrote:
...
Here are the results under Python 2.5:
>>>tester(10)
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
Checking index 0...
[False, 'KeyError', False, 'KeyError', False,
'KeyError', False, 'KeyError', False, 'KeyError']
And here are the results under Python 2.4.3:
>>>tester(10)
[works]
>
Looks like a bug to me.
No problem with 2.5.1c1 here.

--Scott David Daniels
sc***********@a cm.org
Apr 12 '07 #5
En Thu, 12 Apr 2007 01:23:08 -0300, Steven D'Aprano
<st***@REMOVE.T HIS.cybersource .com.auescribió :
On Thu, 12 Apr 2007 00:32:32 -0300, Gabriel Genellina wrote:
>First I want to say that __getitem__ should raise IndexError, not
KeyError, to indicate "not found"

How do you know the Original Poster's class was meant to be a sequence
rather than a mapping?
Ouch, no, sorry, disregard that comment.

--
Gabriel Genellina

Apr 12 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1351
by: Richard Hollenbeck | last post by:
I've asked this question before but over a month later I still don't have an answer. A few people did try to help and I am thankful, but I really didn't get the problem solved. I'll try to ask the question another way. I have a main form for collecting grades for students' activities. Inside the form is a subform which displays four fields: studentID, lName, fName, and score. The first three fields are only to identify the student and...
8
2428
by: Lauren Wilson | last post by:
Hi Folks, We have a solid, five year old Access app that is suddenly behaving oddly after conversion to Access 2002/2003 format. Everything seems to run OK except for a few oddities. The code below is a test form I created to demo the problem. It has a single text box and a command button with the code below. It's function is to determine if a particular folder exists or not. Please note that this code has worked just fine for...
2
1792
by: TB | last post by:
I am seeing a very strange problem as follows... I have a loop where a fair amount of processing is going on and near the top of the loop I access a class that has only static helper functions to perform some calculations. After some number of iterations, randomly, I'll get an uncaught NullValueException error on one of these calls, as if the class name is being treated as an object reference and is null. Here is some psuedo-code to...
1
1952
by: Default | last post by:
Hi, I am new to C#, that is why I am not sure what kind of problem it is: Is VS files corrupted , or something else. that is the problems description: I am working on a small database project. I am not using any data sources Mysql, access etc. Instead I use binary formatter to store and read data. at the beginning the program checks username/password. it does it in the following way: if(form2.initialized) { for(int i=0;...
5
1068
by: John | last post by:
I have created a program that accesses a flat 2 dimensional array and have developed a routine to sum the four neighbors of a specific row/column position. Here is an example, this will sum all the values of row 1, column 1 (base 0) which is the number 5 int a = {1,2,3,4,5,6,7,8,9}; int* pa = &a; // row 1, column 0 (i.e. number 4)
4
1875
by: solex | last post by:
Hello, I am in the process of converting a project from VB6 to DotNet and have noticed that some strange behavior with the TreeView Control (1) when setting the NodeFont property to Bold I cannot see the complete text. (2) when selecting a child node that has a different icon from its parent, it takes on the parents' icon.
0
1135
by: birdinhand | last post by:
Hello, all. After trying to wade through a great deal of undocumented and uncommented code in order to speed up a frame capture rate, I've decided that, for my sanity and that of my boss and any coders to follow me, I should start over and write it myself. I reuse a great deal of the old code, but I can't really get much further until I get the passthrough working (Passthrough is the 'live' video feed captured by the camera and card).
0
3577
by: ivb | last post by:
Hi all, I am using DB2 8.1.11.1 on NT with ASP.NET 1.1 When application make connection to database (via ADO.NET), it set "Connection timeout" parameter to 30 seconds. After, when my webpage requests database, and query execution time exceeds 30 seconds, the following error reported: ===
3
1523
by: sara | last post by:
Very strange behavior, but I suspect some is A2K and some might be for me to correct. Just trying to see if anyone can help and advise. We have a database that's been running for a few years with no problems. We continuously add queries and reports. We're up to about 700 queries (no, not all are used and most are parameter queries - the business asks a LOT of questions!), and under 250 reports and fewer than 15 forms. Data is...
8
3229
by: FBM | last post by:
Hi there, I am puzzled with the behavior of my code.. I am working on a networking stuff, and debugging with eclipse (GNU gdb 6.6-debian).. The problem I am experiencing is the following: Whenever I declare the sockaddr_in structure inside the main, the debugger crashes at line X*, not being able to access argv parameters (see code below). It is very strange.. by only being there, sockaddr_in does not allow me to question argc...
0
9776
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11096
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10716
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10400
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9552
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7953
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5780
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4597
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3223
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.