<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.18.1">
</HEAD>
<BODY>
Hi all,<BR>
<BR>
I'm hitting the recursion limit in my code (well, somewhere inside Twisted, that is), and I'd appreciate any insight as to why. I wouldn't think what I'm doing -- returning a callback from method A which calls method B, which then in turn calls method A again -- would be controversial, since I'd assume Python would be letting go of the stack for method A, but I guess there's more to it than that.<BR>
<BR>
Code demonstrating the issue follows. Running it results in:<BR>
&nbsp;&nbsp;&nbsp; File &quot;/usr/lib/python2.5/site-packages/twisted/python/reflect.py&quot;, line 550, in accumulateBases<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; accumulateBases(base, l, baseClass)<BR>
&nbsp;&nbsp;&nbsp; exceptions.RuntimeError: maximum recursion depth exceeded<BR>
<BR>
(This doesn't actually perfectly reflect my problem in the real code I'm working with. I'm seeing &quot;'maximum recursion depth exceeded' in &lt;bound method DebugInfo.__del__ of &lt;twisted.internet.defer.DebugInfo instance at 0xb1d99b6c&gt;&gt;&quot;, but I assume this is coming from the same basic problem in my code.)<BR>
<BR>
===================================<BR>
<BR>
from twisted.internet import defer, reactor<BR>
<BR>
def yo_print(s, d):<BR>
&nbsp;&nbsp;&nbsp; print s<BR>
&nbsp;&nbsp;&nbsp; d.callback(s)<BR>
&nbsp;&nbsp;&nbsp; return s<BR>
<BR>
def some_deferred(item):<BR>
&nbsp;&nbsp;&nbsp; d = defer.Deferred()<BR>
&nbsp;&nbsp;&nbsp; reactor.callLater(0, lambda: yo_print(item, d))<BR>
&nbsp;&nbsp;&nbsp; return d<BR>
<BR>
def start(items):<BR>
&nbsp;&nbsp;&nbsp; dl = []<BR>
&nbsp;&nbsp;&nbsp; for item in items:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dl.append(some_deferred(item))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if len(dl) &gt; 4:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break<BR>
&nbsp;&nbsp;&nbsp; items = items[len(dl):]<BR>
&nbsp;&nbsp;&nbsp; if dl:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return defer.DeferredList(dl).addCallback(next_batch, items)<BR>
&nbsp;&nbsp;&nbsp; reactor.stop()<BR>
<BR>
def next_batch(_, items):<BR>
&nbsp;&nbsp;&nbsp; return start(items)<BR>
<BR>
if __name__ == '__main__':<BR>
&nbsp;&nbsp;&nbsp; items = []<BR>
&nbsp;&nbsp;&nbsp; for i in range(1651): # 1650 doesn't do it<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; items.append(i)<BR>
&nbsp;&nbsp;&nbsp; print start(items)<BR>
&nbsp;&nbsp;&nbsp; reactor.run()<BR>
&#65279;<BR>
===================================<BR>
<BR>
So I guess the rule is to never, within a callback chain, call a function which was invoked earlier in the callback chain?<BR>
<BR>
Steve
</BODY>
</HTML>