[TIP] Annotated tracebacks

holger krekel holger at merlinux.eu
Tue Oct 21 10:39:34 PDT 2014

On Mon, Oct 20, 2014 at 09:05 +0300, Marius Gedminas wrote:
> On Sat, Oct 18, 2014 at 10:52:47PM +1300, Robert Collins wrote:
> > testtools just had this bug opened on it:
> > 
> > https://github.com/testing-cabal/testtools/issues/111
> > 
> > Which has a few contributing issues but one in particular is that
> > simple tracebacks don't give you the value of variables in parameters,
> > nor of local variables in the trace.
> > 
> > I'm aware of the implementation details that can make showing those
> > values fraught (since __str__ and __repr__ can execute arbitrary
> > code), but I thought I'd do a straw poll here and see who supports the
> > idea of the traceback module itself offering to format such things
> > (e.g. via a locals=False parameter to format_list and friends), which
> > testtools could then backport to older pythons, and use itself to do
> > this.
> +1: the stdlib traceback module ought to let us provide additional
> information per frame.
> I'm ambivalent about outputting _all_ the locals.  My brief experience
> with this (in py.test) leads me to think 99% of the time all that does
> is make the traceback too overwhelmingly long to read comfortably.  (The
> other 1% of the time the extra information is indispensable.)

I agree and because of "--pdb" i rarely use --showlocals today much, even.
One problem is that e.g. in a CI setting you want to see as much info
as possible because it's not always trivial to reproduce the error.
But in an interactive setting you don't want to be overwhelmed.
So i guess by default things should be as terse as is still helpful
but there needs to be an easy way to get more in CI or similar settings.

> In the Zope world[1] we had a convention of showing the value of
> __traceback_info__, if available in the locals of each frame.  Usually
> this would be a tuple with whatever locals the developer thought would
> be useful to see in case of errors.

py.test only has "__tracebackhide__" indicating if this frame should be hidden
in the traceback representation.  That's fairly useful when you want to
write helper functions which produce a failure message but want to have
it shown where the helper was called.

> (There's also __traceback_supplement__, but it's horrible.)
>   [1] https://github.com/zopefoundation/zope.exceptions/blob/master/src/zope/exceptions/exceptionformatter.py
> I've also abused the linecache module to add extra information to
> certain traceback frames: https://gist.github.com/mgedmin/4269249

interesting.  pytest also abuses the filename to allow showing tracebacks
of dynamically exec-ed code (works with py26 and py3X) so that you can just
use "co = py.code.compile(...)" and when using regular unpatched traceback
code it will display it properly. See here:


> > In terms of addressing the implementation details, my thoughts today
> > are to render the traceback once in simple mode, and then once with
> > variables, and if something throws during the variable render, just
> > use the simple one.
> I think
>   foo = <unrepresentable>
> might me more useful.

Yes, definitely.  Given the following line:

    assert not A()   # with A.repr = lambda self: 0/0

pytest gives:

    >       assert not A()
    E       assert not <[ZeroDivisionError("integer division or modulo 
            by zero") raised in repr()] A object at 0x7f44774e3dd0>

so it contains a bit more info than just "unrepresentable".


> Marius Gedminas
> -- 
> We're sysadmins. To us, data is a protocol-overhead.

> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python

More information about the testing-in-python mailing list