[Twisted-Python] Tracebacks being dropped from exceptions when using inlineCallbacks

Phil Christensen phil at bubblehouse.org
Fri Jan 16 19:28:06 EST 2009


On Jan 12, 2009, at 8:36 PM, Terry Jones wrote:
> I think I've finally gotten to the bottom of why exceptions  
> sometimes lose
> their tracebacks when using inlineCallbacks.
[snip]
> We make a failure object, it has a
> traceback, but after passing it to the errback method on a deferred  
> the
> traceback is gone.
>
> This happens because _runCallbacks in defer.py finds no call/errback
> functions to call on the deferred, drops into this code:
>
>        if isinstance(self.result, failure.Failure):
>            self.result.cleanFailure()
>
> which sets the __dict__ on the failure object to the result of the
> failure's __getstate__ method, which sets the traceback to None:
>
>        # added 2003-06-23. See comment above in __init__
>        c['tb'] = None
>
> But the comment in __init__ seems to have been deleted.

The comment was this:

         # added 2003-06-23 by Chris Armstrong. Yes, I actually have a
         # use case where I need this traceback object, and I've made
         # sure that it'll be cleaned up.
         self.tb = tb

presumably referring to the problem with keeping references to  
tracebacks that was a potential pitfall in the Python version of that  
time. That's a non-issue since Python 2.2, though, which is probably  
why the comment got deleted.

Originally all __getstate__ did was stringify the object's state,  
which is probably why cleanFailure calls it directly. It looks to me  
like most of the code from __getstate__ should really be moved into a  
separate method, which would be called from cleanFailure as well as  
__getstate__.

This assumes that __getstate__ would still set c['tb'] to None, but  
that cleanFailure would not. I'm not sure what the repercussions of  
this would be, though. It seems the old problem with keeping  
references to tracebacks is less of an issue now, based on this from  
the current Python docs:

> Note Beginning with Python 2.2, such cycles are automatically  
> reclaimed when garbage collection is enabled and they become  
> unreachable, but it remains more efficient to avoid creating cycles.

I'd appreciate any feedback.

-phil




More information about the Twisted-Python mailing list