[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