Traceback

Traceback object is used to preserve all the information you can get in case of an exception. It preserves: * Information about all stack frames in this thread * Every local and global variable at every stack frame

  • If the variable is picklable, and pickling is enabled, it is pickled on the spot

  • Variable’s _repr_ is always preserved

  • Of course variable name is saved

It also allows to pretty print the exception. Traceback is picklable, so you can safely do so and analyze the exception at your own leisure.

Unpickling _Traceback_ objects in any environment is safe. However, obtaining variable values via _load_value_ might be not.

Usage:

from satella.instrumentation import Traceback

try:
    ...
except:
    tb = Traceback()

    print(tb.pretty_print())    # print stack trace

    tb_p = tb.pickle()  # pickles the traceback

Traceback should be created in the exception it is supposed to capture, as it captures exception info from _sys.exc_info()_. If no exception is in progress, current stack frame will be fetched from inspect.currentframe().

Alternatively, you can pass a <frame> object to Traceback, in order to serialize it, for example:

import sys

frame_1 = next(iter(sys._current_frames().values()))
tb = Traceback(frame_1)
class satella.instrumentation.Traceback(starting_frame: frame | None = None, policy=<class 'satella.instrumentation.trace_back.classes.GenerationPolicy'>)
Class used to preserve exceptions and chains of stack frames.

Picklable.

If starting frame is not given, an exception must be in progress.

You can also convert it to a secure representation, ie. one that will be completely JSON and thus safe to load from untrusted sources. You will not lose the unpicklability of them by doing so, as they can be safely reconstructed (pickle will be encoded as base64 string).

Parameters:
  • starting_frame – frame to start tracking the traceback from. Must be either None, in which case an exception must be in progress and will be taken else must be an instance of <class ‘frame’>.

  • policy – policy for traceback generation

Raises:

ValueError – there is no traceback to get info from! Is any exception in process?

classmethod from_pickle(pick: BytesIO | bytes) Traceback

Load a traceback from a pickle

Parameters:

pick – either bytes or a BytesIO to load it from

Returns:

previously serialized Traceback

Raises:

ValueError – unserialized object is not a Traceback!

pickle() bytes

Returns this instance, pickled

pickle_to(stream: BinaryIO) None

Pickle self to target stream

pretty_format() str

Return a multi-line, pretty-printed representation of all exception data.

Returns:

text

pretty_print(output: ~typing.TextIO = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>) None

Pretty-print the exception

Parameters:

output – a file-like object in text mode

Returns:

unicode

to_json() dict

Return a JSON-able representation of this object

class satella.instrumentation.StoredVariableValue(value: Any, policy: GenerationPolicy | None = None)

Class used to store a variable value. Picklable.

Attributes are:

.repr - a text representation obtained using repr .typeinfo - a text representation of variable’s type .pickle - bytes with pickled (optionally processed) value, or None if

not available

.pickle_type - what is stored in .pickle?

None - nothing “pickle” - normal Python pickle “pickle/gzip” - Python pickle treated with zlib.compress “failed” - could not pickle, pickle contains a UTF-8 text with

human-readable exception reason

“failed/gzip” - compression failed, pickle contains a UTF-8 text with

human-readable exception reason

If value cannot be pickled, it’s repr will be at least preserved.

Note that the value itself won’t be preserved.

Parameters:
  • value – any Python value to preserve

  • policy – policy to use (instance)

load_value()

Return the value that this represents.

WARNING! This may result in importing things from environment, as pickle.loads will be called.

Returns:

stored value - if picklable and was pickled

Raises:

ValueError – value has failed to be pickled or was never pickled

to_json() dict

Return a JSON-able representation of this object

class satella.instrumentation.StackFrame(frame: frame, policy: GenerationPolicy)

Class used to verily preserve stack frames. Picklable.

to_json() dict

Return a JSON-able representation of this object

class satella.instrumentation.GenerationPolicy(enable_pickling: bool = True, compress_at: int = 131072, repr_length_limit: int = 131072, compression_level: int = 6)

A policy that manages generating a traceback

For a “default” policy it’s pretty customizable

Override if need be, and pass the class (or instance) to Traceback

Parameters:
  • enable_pickling – bool, whether to enable pickling at all

  • compress_at – pickles longer than this (bytes) will be compressed

  • repr_length_limit – maximum p_len of __repr__. None for no limit.

  • compression_level – “1” is fastest, “9” is slowest

get_compression_level(data_to_pickle: bytes) int

What compression level to use to pickle this?

Parameters:

data_to_pickle – pickle value

Returns:

int, 1-9, where “1” is the fastest, and “9” is the slowest, but produces best compression

process_repr(r: str) str

Process the string obtained from __repr__ing

Parameters:

r – result of a __repr__ on value

Returns:

processed result

should_compress(pickle_data: bytes) bool

Should this pickle undergo compression?

Parameters:

pickle_data – pickle value

Returns:

bool

should_pickle(value: Any) bool

Should this value be pickled?

Parameters:

value – value candidate

Returns:

bool

There’s a helper function as well

satella.instrumentation.frame_from_traceback(tb: TracebackType) frame

Extract the bottom stack frame from a traceback

Parameters:

tb – traceback to extract the frame

Returns:

bottom stack frame

Dumping all stack frames

satella.instrumentation.dump_frames_on(sig_no: int | None = None, stack_frame: frame | None = None, output: ~typing.TextIO = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>)

Dump all stack frames of all threads including the values of all the local variables.

Parameters:
  • sig_no – signal received. Default is None.

  • stack_frame – Stack frame. Default is None.

  • output – output to print to. Default is stderr

Returns:

satella.instrumentation.install_dump_frames_on(signal_number: int, output: ~typing.TextIO = <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>)

Instruct Python to dump all frames onto output, along with their local variables upon receiving given signal