123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- from __future__ import absolute_import
-
- import sys
- import traceback
-
- __all__ = ['ExceptionInfo', 'Traceback']
-
- DEFAULT_MAX_FRAMES = sys.getrecursionlimit() // 8
-
-
- class _Code(object):
-
- def __init__(self, code):
- self.co_filename = code.co_filename
- self.co_name = code.co_name
- self.co_argcount = code.co_argcount
- self.co_cellvars = ()
- self.co_firstlineno = code.co_firstlineno
- self.co_flags = code.co_flags
- self.co_freevars = ()
- self.co_code = b''
- self.co_lnotab = b''
- self.co_names = code.co_names
- self.co_nlocals = code.co_nlocals
- self.co_stacksize = code.co_stacksize
- self.co_varnames = ()
-
-
- class _Frame(object):
- Code = _Code
-
- def __init__(self, frame):
- self.f_builtins = {}
- self.f_globals = {
- "__file__": frame.f_globals.get("__file__", "__main__"),
- "__name__": frame.f_globals.get("__name__"),
- "__loader__": None,
- }
- self.f_locals = fl = {}
- try:
- fl["__traceback_hide__"] = frame.f_locals["__traceback_hide__"]
- except KeyError:
- pass
- self.f_trace = None
- self.f_exc_traceback = None
- self.f_exc_type = None
- self.f_exc_value = None
- self.f_code = self.Code(frame.f_code)
- self.f_lineno = frame.f_lineno
- self.f_lasti = frame.f_lasti
- # don't want to hit https://bugs.python.org/issue21967
- self.f_restricted = False
-
-
- class _Object(object):
-
- def __init__(self, **kw):
- [setattr(self, k, v) for k, v in kw.items()]
-
-
- class _Truncated(object):
-
- def __init__(self):
- self.tb_lineno = -1
- self.tb_frame = _Object(
- f_globals={"__file__": "",
- "__name__": "",
- "__loader__": None},
- f_fileno=None,
- f_code=_Object(co_filename="...",
- co_name="[rest of traceback truncated]"),
- )
- self.tb_next = None
- self.tb_lasti = 0
-
-
- class Traceback(object):
- Frame = _Frame
-
- def __init__(self, tb, max_frames=DEFAULT_MAX_FRAMES, depth=0):
- self.tb_frame = self.Frame(tb.tb_frame)
- self.tb_lineno = tb.tb_lineno
- self.tb_lasti = tb.tb_lasti
- self.tb_next = None
- if tb.tb_next is not None:
- if depth <= max_frames:
- self.tb_next = Traceback(tb.tb_next, max_frames, depth + 1)
- else:
- self.tb_next = _Truncated()
-
-
- class ExceptionInfo(object):
- """Exception wrapping an exception and its traceback.
-
- :param exc_info: The exception info tuple as returned by
- :func:`sys.exc_info`.
-
- """
-
- #: Exception type.
- type = None
-
- #: Exception instance.
- exception = None
-
- #: Pickleable traceback instance for use with :mod:`traceback`
- tb = None
-
- #: String representation of the traceback.
- traceback = None
-
- #: Set to true if this is an internal error.
- internal = False
-
- def __init__(self, exc_info=None, internal=False):
- self.type, self.exception, tb = exc_info or sys.exc_info()
- try:
- self.tb = Traceback(tb)
- self.traceback = ''.join(
- traceback.format_exception(self.type, self.exception, tb),
- )
- self.internal = internal
- finally:
- del(tb)
-
- def __str__(self):
- return self.traceback
-
- def __repr__(self):
- return "<ExceptionInfo: %r>" % (self.exception, )
-
- @property
- def exc_info(self):
- return self.type, self.exception, self.tb
|