I am refactoring a Python signal processing framework because of a maximum recurrence depth error we experienced.
The most likely explanation for the error is that sometimes a large number of instances of a single class are created recursively from the class' its init method. Indeed experiments simulating this situation lead to a Exception RuntimeError: 'maximum recursion depth exceeded'.
When I move creating the next element in the chain to the container managing these objects the problem seems to disappear, this despite building in my naive understanding a call stack of the same depth. I call create through all the previously created objects. (see example code).
I am inclined to conclude that the recursion depth limit is somehow set per object (be it a class or an instance). Which when creating recursively via init probably puts everything on the stack of the class, where as if we create them recursively through a line of instances of the same class all the objects will have very limited recursion depth.
I am seeking some confirmation for this hypothesis, but find it hard to get either confirmation or refutation.
import sys
class Chunk(object):
    pre=None
    post=None
    def __init__(self, container,pre):
        print 'Chunk Created'
        self.pre=pre
        self.container=container
    def create(self,x):
        if self.post == None:
            self.post=Chunk(self.container,self)
            newChunk =self.post
        else:
            newChunk =self.post.create(x+1)
        return newChunk
    def droprefs(self):
        print 'refcount droprefs start: ', sys.getrefcount(self)
        if not self.pre ==None:
            self.pre.droprefs()
        self.pre=None
        self.post=None
        self.container=None
        print 'refcount droprefs end: ', sys.getrefcount(self)
    def claimContainer(self):
        self.container.setmasterchunk(self)
        self.pre.droprefs()
        self.pre=None
class Container(object):
    masterchunk=None
    def __init__(self):
        self.masterchunk=Chunk(self, None)
    def setmasterchunk(self, chunk):
        print 'refcount 5: ', sys.getrefcount(self.masterchunk)
        self.masterchunk=chunk
        print 'refcount 6: ', sys.getrefcount(self.masterchunk)
    def testrecursion(self,n):
        for i in range(n):
            print 'refcount 6: ', sys.getrefcount(self.masterchunk)
            newChunk=self.masterchunk.create(1)
        return newChunk
    def testhistoryremoval(self,chunk):
        chunk.claimContainer()
if __name__ == '__main__':
    C=Container()
    middle=C.testrecursion(300)
    last=C.testrecursion(600)
    last=C.testhistoryremoval(middle)
    if middle== C.masterchunk:
        print 'SUCCESS'
Note added:
Code showing the maximum recursion depth:
import sys
from time import sleep
class Chunk(object):
    pre=None
    post=None
    def __init__(self, container,pre,n):
        print 'Chunk Created'
        self.pre=pre
        self.container=container
        if n>0:
            self.post=Chunk(self.container,self,n-1)
    def droprefs(self):
        print 'refcount droprefs start: ', sys.getrefcount(self)
        if not self.pre ==None:
            self.pre.droprefs()
        self.pre=None
        self.post=None
        self.container=None
        print 'refcount droprefs end: ', sys.getrefcount(self)
    def claimContainer(self):
        self.container.setmasterchunk(self)
        self.pre.droprefs()
        self.pre=None
class Container(object):
    masterchunk=None
    def __init__(self):
        pass
    def setmasterchunk(self, chunk):
        print 'refcount 5: ', sys.getrefcount(self.masterchunk)
        self.masterchunk=chunk
        print 'refcount 6: ', sys.getrefcount(self.masterchunk)
    def testrecursion(self,n):
        self.masterchunk=Chunk(self,None,n)
if __name__ == '__main__':
    print('Try 10')
    C0=Container()
    C0.testrecursion(10)
    sleep(2)
    print('Try 1000')
    C1=Container()
    C1.testrecursion(1000)
 
     
     
    