"reraise" & Exception Transformation (was Re: Modules implicitly exposing exceptions from other modules)

Bernhard Herzog herzog at online.de
Wed Feb 16 16:36:56 EST 2000


"Barry A. Warsaw" <bwarsaw at cnri.reston.va.us> writes:

> >>>>> "RH" == Randall Hopper <aa8vb at yahoo.com> writes:
> 
>     RH> Maybe a "reraise <exception>" statement in Python 2.0?
> 
> TMSA (Time Machine Strikes Again):
> 
> -------------------- snip snip --------------------
> import sys
> 
> def foo():
>     raise NameError
> 
> def bar():
>     foo()
> 
> def baz():
>     try:
>         bar()
>     except NameError:
>         tpe, val, tb = sys.exc_info()
>         raise AttributeError, None, tb

Binding the traceback to a local variable creates a cyclic reference, as
the library documentation clearly warns:


     *Warning:* assigning the TRACEBACK return value to a local
     variable in a function that is handling an exception will cause a
     circular reference. This will prevent anything referenced by a
     local variable in the same function or by the traceback from being
     garbage collected.  Since most functions don't need access to the
     traceback, the best solution is to use something like `type, value
     = sys.exc_info()[:2]' to extract only the exception type and
     value.  If you do need the traceback, make sure to delete it after
     use (best done with a `try' ... `finally' statement) or to call
     `exc_info()' in a function that does not itself handle an
     exception.

So, a better way to reraise the exception is

def baz():
    try:
        bar()
    except NameError:
	raise AttributeError, None, sys.exc_info()[-1]


-- 
Bernhard Herzog   | Sketch, a drawing program for Unix
herzog at online.de  | http://sketch.sourceforge.net/



More information about the Python-list mailing list