views:

235

answers:

2

Hi all. I'm working on a Python library used by third-party developers to write extensions for our core application.

I'd like to know if it's possible to modify the traceback when raising exceptions, so the last stack frame is the call to the library function in the developer's code, rather than the line in the library that raised the exception. There are also a few frames at the bottom of the stack containing references to functions used when first loading the code that I'd ideally like to remove too.

Thanks in advance for any advice!

A: 

Take a look at what jinja2 does here:

http://bitbucket.org/mitsuhiko/jinja2-main/src/tip/jinja2/debug.py

It's ugly, but it seems to do what you need done. I won't copy-paste the example here because it's long.

Carl Hill
+1  A: 

What about not changing the traceback? The two things you request can both be done more easily in a different way.

  1. If the exception from the library is caught in the developer's code and a new exception is raised instead, the original traceback will of course be tossed. This is how exceptions are generally handled... if you just allow the original exception to be raised but you munge it to remove all the "upper" frames, the actual exception won't make sense since the last line in the traceback would not itself be capable of raising the exception.
  2. To strip out the last few frames, you can request that your tracebacks be shortened... things like traceback.print_exception() take a "limit" parameter which you could use to skip the last few entries.

That said, it should be quite possible to munge the tracebacks if you really need to... but where would you do it? If in some wrapper code at the very top level, then you could simply grab the traceback, take a slice to remove the parts you don't want, and then use functions in the "traceback" module to format/print as desired.

Peter Hansen