Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from __future__ import absolute_import 

2 

3import sys 

4import traceback 

5 

6__all__ = ['ExceptionInfo', 'Traceback'] 

7 

8DEFAULT_MAX_FRAMES = sys.getrecursionlimit() // 8 

9 

10 

11class _Code(object): 

12 

13 def __init__(self, code): 

14 self.co_filename = code.co_filename 

15 self.co_name = code.co_name 

16 self.co_argcount = code.co_argcount 

17 self.co_cellvars = () 

18 self.co_firstlineno = code.co_firstlineno 

19 self.co_flags = code.co_flags 

20 self.co_freevars = () 

21 self.co_code = b'' 

22 self.co_lnotab = b'' 

23 self.co_names = code.co_names 

24 self.co_nlocals = code.co_nlocals 

25 self.co_stacksize = code.co_stacksize 

26 self.co_varnames = () 

27 

28 

29class _Frame(object): 

30 Code = _Code 

31 

32 def __init__(self, frame): 

33 self.f_builtins = {} 

34 self.f_globals = { 

35 "__file__": frame.f_globals.get("__file__", "__main__"), 

36 "__name__": frame.f_globals.get("__name__"), 

37 "__loader__": None, 

38 } 

39 self.f_locals = fl = {} 

40 try: 

41 fl["__traceback_hide__"] = frame.f_locals["__traceback_hide__"] 

42 except KeyError: 

43 pass 

44 self.f_back = None 

45 self.f_trace = None 

46 self.f_exc_traceback = None 

47 self.f_exc_type = None 

48 self.f_exc_value = None 

49 self.f_code = self.Code(frame.f_code) 

50 self.f_lineno = frame.f_lineno 

51 self.f_lasti = frame.f_lasti 

52 # don't want to hit https://bugs.python.org/issue21967 

53 self.f_restricted = False 

54 

55 

56class _Object(object): 

57 

58 def __init__(self, **kw): 

59 [setattr(self, k, v) for k, v in kw.items()] 

60 

61 

62class _Truncated(object): 

63 

64 def __init__(self): 

65 self.tb_lineno = -1 

66 self.tb_frame = _Object( 

67 f_globals={"__file__": "", 

68 "__name__": "", 

69 "__loader__": None}, 

70 f_fileno=None, 

71 f_code=_Object(co_filename="...", 

72 co_name="[rest of traceback truncated]"), 

73 ) 

74 self.tb_next = None 

75 self.tb_lasti = 0 

76 

77 

78class Traceback(object): 

79 Frame = _Frame 

80 

81 def __init__(self, tb, max_frames=DEFAULT_MAX_FRAMES, depth=0): 

82 self.tb_frame = self.Frame(tb.tb_frame) 

83 self.tb_lineno = tb.tb_lineno 

84 self.tb_lasti = tb.tb_lasti 

85 self.tb_next = None 

86 if tb.tb_next is not None: 

87 if depth <= max_frames: 

88 self.tb_next = Traceback(tb.tb_next, max_frames, depth + 1) 

89 else: 

90 self.tb_next = _Truncated() 

91 

92 

93class ExceptionInfo(object): 

94 """Exception wrapping an exception and its traceback. 

95 

96 :param exc_info: The exception info tuple as returned by 

97 :func:`sys.exc_info`. 

98 

99 """ 

100 

101 #: Exception type. 

102 type = None 

103 

104 #: Exception instance. 

105 exception = None 

106 

107 #: Pickleable traceback instance for use with :mod:`traceback` 

108 tb = None 

109 

110 #: String representation of the traceback. 

111 traceback = None 

112 

113 #: Set to true if this is an internal error. 

114 internal = False 

115 

116 def __init__(self, exc_info=None, internal=False): 

117 self.type, self.exception, tb = exc_info or sys.exc_info() 

118 try: 

119 self.tb = Traceback(tb) 

120 self.traceback = ''.join( 

121 traceback.format_exception(self.type, self.exception, tb), 

122 ) 

123 self.internal = internal 

124 finally: 

125 del(tb) 

126 

127 def __str__(self): 

128 return self.traceback 

129 

130 def __repr__(self): 

131 return "<%s: %r>" % (self.__class__.__name__, self.exception, ) 

132 

133 @property 

134 def exc_info(self): 

135 return self.type, self.exception, self.tb