[IronPython] in operator calls __getitem__ on class that has __len__ and __iter__ defined

Dino Viehland dinov at microsoft.com
Thu Nov 20 17:30:49 CET 2008

Interesting, the docs would seem to indicate our behavior is correct:

For user-defined classes which do not define __contains__() and do define __getitem__(), x in y is true if and only if there is a non-negative integer index i such that x == y[i], and all lower integer indices do not raise IndexError exception. (If any other exception is raised, it is as if in raised that exception).

If and only if is pretty strong language ☺  But we can start looking for __iter__ after looking for __contains__.

From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Glenn Jones
Sent: Thursday, November 20, 2008 7:23 AM
To: users at lists.ironpython.com
Subject: [IronPython] in operator calls __getitem__ on class that has __len__ and __iter__ defined

Yet another weirdness, but not a blocker for us:

With this object:

class o(object):
  def __iter__(self):
    print "iter"
    return iter([1, 2, 3])
  def __getitem__(self, index):
    print "getitem"
    return [1, 2, 3][index]
  def __len__(self):
    print "len"
    return 3

>>> p = o()
>>> 1 in p

IronPython 2 source drop 43741:
>>> p = o()
>>> 1 in p

It looks like CPython is treating it like a sequence and IronPython 2 is treating it like a dict.

We have worked around this by implementing __contains__

Raised as Issue 19678 on CodePlex.

PS: How can we format code blocks on CodePlex?

Glenn & Orestis

More information about the Ironpython-users mailing list