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: Optional[frame] = 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: Union[_io.BytesIO, bytes]) → satella.instrumentation.trace_back.trace_back.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: 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: Optional[satella.instrumentation.trace_back.classes.GenerationPolicy] = 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: satella.instrumentation.trace_back.classes.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: traceback) → 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: Optional[int] = None, stack_frame: Optional[frame] = None, output: 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: 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