Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a traceback object

I want to create a traceback like the one returned by sys.exc_info()[2]. I don't want a list of lines, I want an actual traceback object:

<traceback object at 0x7f6575c37e48>

How can I do this? My goal is to have it include the current stack minus one frame, so it looks the the caller is the most recent call.

like image 460
Colton Leekly-Winslow Avatar asked Nov 25 '14 23:11

Colton Leekly-Winslow


People also ask

How do you create a traceback in Python?

traceback. format_exc(limit = None, chain = True) : This is like print_exc(limit) except it returns a string instead of printing to a file. traceback. format_tb(tb, limit = None) : shorthand for format_list(extract_tb(tb, limit)).

What is a traceback object?

This is useful when you want to print stack traces under program control, such as in a “wrapper” around the interpreter. The module uses traceback objects — this is the object type that is stored in the sys. last_traceback variable and returned as the third item from sys. exc_info() .

What is meant by traceback in Python?

In Python, A traceback is a report containing the function calls made in your code at a specific point i.e when you get an error it is recommended that you should trace it backward(traceback). Whenever the code gets an exception, the traceback will give the information about what went wrong in the code.

What is traceback stack?

A traceback is a stack trace from the point of an exception handler down the call chain to the point where the exception was raised. You can also work with the current call stack up from the point of a call (and without the context of an error), which is useful for finding out the paths being followed into a function.


2 Answers

There's no documented way to create traceback objects.

None of the functions in the traceback module create them. You can of course access the type as types.TracebackType, but if you call its constructor you just get a TypeError: cannot create 'traceback' instances.

The reason for this is that tracebacks contain references to internals that you can't actually access or generate from within Python.


However, you can access stack frames, and everything else you'd need to simulate a traceback is trivial. You can even write a class that has tb_frame, tb_lasti, tb_lineno, and tb_next attributes (using the info you can get from traceback.extract_stack and one of the inspect functions), which will look exactly like a traceback to any pure-Python code.

So there's a good chance that whatever you really want to do is doable, even though what you're asking for is not.

like image 153
abarnert Avatar answered Oct 12 '22 11:10

abarnert


Since Python 3.7 you can create traceback objects dynamically from Python.
To create traceback identical to one created by raise:

raise Exception()

use this:

import sys
import types

def exception_with_traceback(message):
    tb = None
    depth = 0
    while True:
        try:
            frame = sys._getframe(depth)
            depth += 1
        except ValueError as exc:
            break

        tb = types.TracebackType(tb, frame, frame.f_lasti, frame.f_lineno)

    return Exception(message).with_traceback(tb)

Relevant documentation is here:

  • https://docs.python.org/3/library/types.html#types.TracebackType
  • https://docs.python.org/3/reference/datamodel.html#traceback-objects
  • https://docs.python.org/3/library/sys.html#sys._getframe
like image 37
Zbyl Avatar answered Oct 12 '22 12:10

Zbyl