github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/stdlib/traceback.py (about) 1 """Extract, format and print information about Python stack traces.""" 2 3 import linecache 4 import sys 5 import types 6 7 __all__ = ['extract_stack', 'extract_tb', 'format_exception', 8 'format_exception_only', 'format_list', 'format_stack', 9 'format_tb', 'print_exc', 'format_exc', 'print_exception', 10 'print_last', 'print_stack', 'print_tb', 'tb_lineno'] 11 12 def _print(file, str='', terminator='\n'): 13 file.write(str+terminator) 14 15 16 def print_list(extracted_list, file=None): 17 """Print the list of tuples as returned by extract_tb() or 18 extract_stack() as a formatted stack trace to the given file.""" 19 if file is None: 20 file = sys.stderr 21 for filename, lineno, name, line in extracted_list: 22 _print(file, 23 ' File "%s", line %d, in %s' % (filename,lineno,name)) 24 if line: 25 _print(file, ' %s' % line.strip()) 26 27 def format_list(extracted_list): 28 """Format a list of traceback entry tuples for printing. 29 30 Given a list of tuples as returned by extract_tb() or 31 extract_stack(), return a list of strings ready for printing. 32 Each string in the resulting list corresponds to the item with the 33 same index in the argument list. Each string ends in a newline; 34 the strings may contain internal newlines as well, for those items 35 whose source text line is not None. 36 """ 37 list = [] 38 for filename, lineno, name, line in extracted_list: 39 item = ' File "%s", line %d, in %s\n' % (filename,lineno,name) 40 if line: 41 item = item + ' %s\n' % line.strip() 42 list.append(item) 43 return list 44 45 46 def print_tb(tb, limit=None, file=None): 47 """Print up to 'limit' stack trace entries from the traceback 'tb'. 48 49 If 'limit' is omitted or None, all entries are printed. If 'file' 50 is omitted or None, the output goes to sys.stderr; otherwise 51 'file' should be an open file or file-like object with a write() 52 method. 53 """ 54 if file is None: 55 file = sys.stderr 56 if limit is None: 57 if hasattr(sys, 'tracebacklimit'): 58 limit = sys.tracebacklimit 59 n = 0 60 while tb is not None and (limit is None or n < limit): 61 f = tb.tb_frame 62 lineno = tb.tb_lineno 63 co = f.f_code 64 filename = co.co_filename 65 name = co.co_name 66 _print(file, 67 ' File "%s", line %d, in %s' % (filename, lineno, name)) 68 linecache.checkcache(filename) 69 line = linecache.getline(filename, lineno, f.f_globals) 70 if line: _print(file, ' ' + line.strip()) 71 tb = tb.tb_next 72 n = n+1 73 74 def format_tb(tb, limit = None): 75 """A shorthand for 'format_list(extract_tb(tb, limit))'.""" 76 return format_list(extract_tb(tb, limit)) 77 78 def extract_tb(tb, limit = None): 79 """Return list of up to limit pre-processed entries from traceback. 80 81 This is useful for alternate formatting of stack traces. If 82 'limit' is omitted or None, all entries are extracted. A 83 pre-processed stack trace entry is a quadruple (filename, line 84 number, function name, text) representing the information that is 85 usually printed for a stack trace. The text is a string with 86 leading and trailing whitespace stripped; if the source is not 87 available it is None. 88 """ 89 if limit is None: 90 if hasattr(sys, 'tracebacklimit'): 91 limit = sys.tracebacklimit 92 list = [] 93 n = 0 94 while tb is not None and (limit is None or n < limit): 95 f = tb.tb_frame 96 lineno = tb.tb_lineno 97 co = f.f_code 98 filename = co.co_filename 99 name = co.co_name 100 linecache.checkcache(filename) 101 line = linecache.getline(filename, lineno, f.f_globals) 102 if line: line = line.strip() 103 else: line = None 104 list.append((filename, lineno, name, line)) 105 tb = tb.tb_next 106 n = n+1 107 return list 108 109 110 def print_exception(etype, value, tb, limit=None, file=None): 111 """Print exception up to 'limit' stack trace entries from 'tb' to 'file'. 112 113 This differs from print_tb() in the following ways: (1) if 114 traceback is not None, it prints a header "Traceback (most recent 115 call last):"; (2) it prints the exception type and value after the 116 stack trace; (3) if type is SyntaxError and value has the 117 appropriate format, it prints the line where the syntax error 118 occurred with a caret on the next line indicating the approximate 119 position of the error. 120 """ 121 if file is None: 122 # TODO: Use sys.stderr when that's implemented. 123 file = open('/dev/stderr', 'w') 124 #file = sys.stderr 125 if tb: 126 _print(file, 'Traceback (most recent call last):') 127 print_tb(tb, limit, file) 128 lines = format_exception_only(etype, value) 129 for line in lines: 130 _print(file, line, '') 131 132 def format_exception(etype, value, tb, limit = None): 133 """Format a stack trace and the exception information. 134 135 The arguments have the same meaning as the corresponding arguments 136 to print_exception(). The return value is a list of strings, each 137 ending in a newline and some containing internal newlines. When 138 these lines are concatenated and printed, exactly the same text is 139 printed as does print_exception(). 140 """ 141 if tb: 142 list = ['Traceback (most recent call last):\n'] 143 list = list + format_tb(tb, limit) 144 else: 145 list = [] 146 list = list + format_exception_only(etype, value) 147 return list 148 149 def format_exception_only(etype, value): 150 """Format the exception part of a traceback. 151 152 The arguments are the exception type and value such as given by 153 sys.last_type and sys.last_value. The return value is a list of 154 strings, each ending in a newline. 155 156 Normally, the list contains a single string; however, for 157 SyntaxError exceptions, it contains several lines that (when 158 printed) display detailed information about where the syntax 159 error occurred. 160 161 The message indicating which exception occurred is always the last 162 string in the list. 163 164 """ 165 166 # An instance should not have a meaningful value parameter, but 167 # sometimes does, particularly for string exceptions, such as 168 # >>> raise string1, string2 # deprecated 169 # 170 # Clear these out first because issubtype(string1, SyntaxError) 171 # would raise another exception and mask the original problem. 172 if (isinstance(etype, BaseException) or 173 # isinstance(etype, types.InstanceType) or 174 etype is None or type(etype) is str): 175 return [_format_final_exc_line(etype, value)] 176 177 stype = etype.__name__ 178 179 if not issubclass(etype, SyntaxError): 180 return [_format_final_exc_line(stype, value)] 181 182 # It was a syntax error; show exactly where the problem was found. 183 lines = [] 184 try: 185 msg, (filename, lineno, offset, badline) = value.args 186 except Exception: 187 pass 188 else: 189 filename = filename or "<string>" 190 lines.append(' File "%s", line %d\n' % (filename, lineno)) 191 if badline is not None: 192 lines.append(' %s\n' % badline.strip()) 193 if offset is not None: 194 caretspace = badline.rstrip('\n') 195 offset = min(len(caretspace), offset) - 1 196 caretspace = caretspace[:offset].lstrip() 197 # non-space whitespace (likes tabs) must be kept for alignment 198 caretspace = ((c.isspace() and c or ' ') for c in caretspace) 199 lines.append(' %s^\n' % ''.join(caretspace)) 200 value = msg 201 202 lines.append(_format_final_exc_line(stype, value)) 203 return lines 204 205 def _format_final_exc_line(etype, value): 206 """Return a list of a single line -- normal case for format_exception_only""" 207 valuestr = _some_str(value) 208 if value is None or not valuestr: 209 line = "%s\n" % etype 210 else: 211 line = "%s: %s\n" % (etype, valuestr) 212 return line 213 214 def _some_str(value): 215 try: 216 return str(value) 217 except Exception: 218 pass 219 try: 220 value = unicode(value) 221 return value.encode("ascii", "backslashreplace") 222 except Exception: 223 pass 224 return '<unprintable %s object>' % type(value).__name__ 225 226 227 def print_exc(limit=None, file=None): 228 """Shorthand for 'print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file)'. 229 (In fact, it uses sys.exc_info() to retrieve the same information 230 in a thread-safe way.)""" 231 if file is None: 232 # TODO: Use sys.stderr when that's implemented. 233 file = open('/dev/stderr', 'w') 234 #file = sys.stderr 235 try: 236 etype, value, tb = sys.exc_info() 237 print_exception(etype, value, tb, limit, file) 238 finally: 239 etype = value = tb = None 240 241 242 def format_exc(limit=None): 243 """Like print_exc() but return a string.""" 244 try: 245 etype, value, tb = sys.exc_info() 246 return ''.join(format_exception(etype, value, tb, limit)) 247 finally: 248 etype = value = tb = None 249 250 251 def print_last(limit=None, file=None): 252 """This is a shorthand for 'print_exception(sys.last_type, 253 sys.last_value, sys.last_traceback, limit, file)'.""" 254 if not hasattr(sys, "last_type"): 255 raise ValueError("no last exception") 256 if file is None: 257 file = sys.stderr 258 print_exception(sys.last_type, sys.last_value, sys.last_traceback, 259 limit, file) 260 261 262 def print_stack(f=None, limit=None, file=None): 263 """Print a stack trace from its invocation point. 264 265 The optional 'f' argument can be used to specify an alternate 266 stack frame at which to start. The optional 'limit' and 'file' 267 arguments have the same meaning as for print_exception(). 268 """ 269 if f is None: 270 try: 271 raise ZeroDivisionError 272 except ZeroDivisionError: 273 f = sys.exc_info()[2].tb_frame.f_back 274 print_list(extract_stack(f, limit), file) 275 276 def format_stack(f=None, limit=None): 277 """Shorthand for 'format_list(extract_stack(f, limit))'.""" 278 if f is None: 279 try: 280 raise ZeroDivisionError 281 except ZeroDivisionError: 282 f = sys.exc_info()[2].tb_frame.f_back 283 return format_list(extract_stack(f, limit)) 284 285 def extract_stack(f=None, limit = None): 286 """Extract the raw traceback from the current stack frame. 287 288 The return value has the same format as for extract_tb(). The 289 optional 'f' and 'limit' arguments have the same meaning as for 290 print_stack(). Each item in the list is a quadruple (filename, 291 line number, function name, text), and the entries are in order 292 from oldest to newest stack frame. 293 """ 294 if f is None: 295 try: 296 raise ZeroDivisionError 297 except ZeroDivisionError: 298 f = sys.exc_info()[2].tb_frame.f_back 299 if limit is None: 300 if hasattr(sys, 'tracebacklimit'): 301 limit = sys.tracebacklimit 302 list = [] 303 n = 0 304 while f is not None and (limit is None or n < limit): 305 lineno = f.f_lineno 306 co = f.f_code 307 filename = co.co_filename 308 name = co.co_name 309 linecache.checkcache(filename) 310 line = linecache.getline(filename, lineno, f.f_globals) 311 if line: line = line.strip() 312 else: line = None 313 list.append((filename, lineno, name, line)) 314 f = f.f_back 315 n = n+1 316 list.reverse() 317 return list 318 319 def tb_lineno(tb): 320 """Calculate correct line number of traceback given in tb. 321 322 Obsolete in 2.3. 323 """ 324 return tb.tb_lineno