Question

Here's a piece of code, which goes into an infinite recursion loop, which consists only of __repr__ function, seemingly calling itself. But I really can't see, how it calls itself. Moreover, I can't even understand, how it was called:

class MyList(list): #this is storage for MyDict objects
    def __init__(self):
        super(MyList, self).__init__()

class MyDict(dict):
    def __init__(self, mylist):
        self.mylist = mylist #mydict remembers mylist, to which it belongs
    def __hash__(self):
        return id(self)
    def __eq__(self, other):
        return self is other
    def __repr__(self):
        return str(self.mylist.index(self)) #!!!this is the crazy repr, going into recursion
    def __str__(self):
        return str(self.__repr__())

mylist = MyList()
mydict = MyDict(mylist)
mydict.update({1:2})
print str(mylist.index(mydict)) #here we die :(

Execution of this code results in:

Traceback (most recent call last):
  File "test_analogue.py", line 20, in <module>
    print str(mylist.index(mydict))
  File "test_analogue.py", line 13, in __repr__
    return str(self.mylist.index(self))
  File "test_analogue.py", line 13, in __repr__
  ... 
  ... (repetition of last 2 lines for ~666 times)
  ...
  File "test_analogue.py", line 13, in __repr__
    return str(self.mylist.index(self))
  RuntimeError: maximum recursion depth exceeded while calling a Python object

Do you understand, how str(mylist.index(mydict)) managed to call __repr__? I'm completely puzzled. Thanks!

Was it helpful?

Solution

>> mylist.index('foo')
ValueError: 'foo' is not in list

You never actually added mydict to mylist, so the index method tries to raise this error. The error contains the repr of the dict. The repr of the dict, of course, tries to look up its index in the list that it isn't in, and this raises an exception, whose error message is calculated using the repr of the dict, which of course, tries to look up its index in the list that it isn't in, and...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top