[Python-3000] self-contained exceptions

tomer filiba tomerfiliba at gmail.com
Thu Jan 4 18:18:12 CET 2007


[Guido]
> > as well as
> > traceback.format_exception (which i greatly dislike).
>
> Why? Because it once insulted you?

because it's tedious, repetitive and unreadable.

try:
    foo
except:
    import traceback
    import sys
    tbtext = "".join(traceback.format_exception(*sys.exc_info()))
    raise RemoteException(tbtext)

it ought to have at least a nicer API, for instance,
tbtext = traceback.format_current()


-tomer

On 1/2/07, Guido van Rossum <guido at python.org> wrote:
> On 1/1/07, tomer filiba <tomerfiliba at gmail.com> wrote:
> > a while back some people suggested having the traceback
> > as an attribute of the exception object, which allows for
> > nested exceptions.
>
> PEP 344, to be precise.
>
> > i would also like to note that having the traceback part of
> > the exception object allows the exception to print itself,
> > i.e., its repr would format the traceback text on it's own.
>
> I'm not sure that's an improvement. I like to b able to have different
> ways of formatting exceptions. And a repr() that's as long as a
> typical traceback isn't a great idea either. Note that currently
> there's nothing to prevent tracebacks from having a repr() that prints
> the exception, and yet this isn't what it does.
>
> > this makes sys.excepthook unnecessary,
>
> Not at all. sys.excepthook can do other things besides formatting the
> exception, and when it does format the exception, it can do so in any
> number of interesting alternative ways (e.g. cgitb.py).
>
> > as well as
> > traceback.format_exception (which i greatly dislike).
>
> Why? Because it once insulted you?
>
> > even if the exception's repr would raise an exception
> > (recursion limit, etc.), that exception would be a builtin
> > one, so we won't end up in a repr-exception-loop.
> >
> > with this approach, sys.excepthook is needless, or at least
> > simplified greatly (just print repr(exc)). for example, exceptions
> > raised by RPyC have a special attribute to them -- remote_traceback,
> > which is the text of the remote traceback. currently i have to
> > replace excepthook to have it displayed with the local exception
> > traceback, which is means just importing RPyC messes with
> > your interpreter's internals, and may cause problems when
> > another library installs its own hook.
> >
> > apart from self-repr'ing, nested exceptions are very useful too:
> >
> > try:
> >     foo()
> > except Exception, ex:
> >     raise MyException("something happened", nested = ex)
>
> It really looks like you've never read PEP 344, or you wouldn't be
> introducing a different way to spell what it already proposes.
>
> > so that when i pdb.pm() my code, i can inspect the inner
> > exception too (which is desirable of course).
> >
> > the major argument against having the traceback part of
> > the exception object was increasing memory consumption,
> > so that exceptions are no longer "light weight" (as used by
> > StopIteration, etc.)
>
> Where did you hear this? It is not *my* objection.
>
> > i don't see why this argument stands. the traceback object
> > exists either way, the only question is in what namespace
> > it exists, and the fact it may "live longer" than necessary,
> > i.e., the traceback exists for as long as the exception object
> > exists.
> >
> > i don't think it's really that bad. first, for StopIteration, the exception
> > object is decref()ed immediately after being raised. moreover,
> > since no one is expected to see that traceback, it can be set
> > directly to None, i.e., a PyErr_SetStopIter() function which sets
> > exc.traceback to None internally.
> >
> > other than that, you *want* to keep the traceback alive. therefore,
> > i suggest adding two new attributes to the exception class:
> > * traceback - the traceback object, or None
> > * nested - nested ("inner") exception, or None
> >
> > Exception.__repr__ will be extended to formatting the
> > traceback (if not None) and formatting all the nested
> > exceptions (+ detect recursion).
> >
> > this may be an expensive operation, but as it only happens
> > when the exceptions is printed to stderr, it's negligible.
>
> I believe the main argument *against* having the tb included in the
> exception is that it would greatly increase the cyclic nature of
> tracebacks and stack frames, which in turn would cause lots of code to
> break due to late GC'ing of unclosed files, etc. For example, this
> code:
>
> try:
>   1/0
> except Exception, err:
>   pass
>
> will introduce a cycle from err -> traceback -> stack frame -> err,
> keeping all locals in the same scope alive until the next GC happens.
>
> --
> --Guido van Rossum (home page: http://www.python.org/~guido/)
>


More information about the Python-3000 mailing list