tbtools.py (7990B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\werkzeug\debug\tbtools.py 2 import re 3 import os 4 import sys 5 import inspect 6 import traceback 7 import codecs 8 from tokenize import TokenError 9 from werkzeug.utils import cached_property 10 from werkzeug.debug.console import Console 11 from werkzeug.debug.utils import render_template 12 _coding_re = re.compile('coding[:=]\\s*([-\\w.]+)') 13 _line_re = re.compile('^(.*?)$(?m)') 14 _funcdef_re = re.compile('^(\\s*def\\s)|(.*(?<!\\w)lambda(:|\\s))|^(\\s*@)') 15 UTF8_COOKIE = '\xef\xbb\xbf' 16 system_exceptions = (SystemExit, KeyboardInterrupt) 17 try: 18 system_exceptions += (GeneratorExit,) 19 except NameError: 20 pass 21 22 def get_current_traceback(ignore_system_exceptions = False, show_hidden_frames = False, skip = 0): 23 exc_type, exc_value, tb = sys.exc_info() 24 if ignore_system_exceptions and exc_type in system_exceptions: 25 raise 26 for x in xrange(skip): 27 if tb.tb_next is None: 28 break 29 tb = tb.tb_next 30 31 tb = Traceback(exc_type, exc_value, tb) 32 if not show_hidden_frames: 33 tb.filter_hidden_frames() 34 return tb 35 36 37 class Line(object): 38 __slots__ = ('lineno', 'code', 'in_frame', 'current') 39 40 def __init__(self, lineno, code): 41 self.lineno = lineno 42 self.code = code 43 self.in_frame = False 44 self.current = False 45 46 def classes(self): 47 rv = ['line'] 48 if self.in_frame: 49 rv.append('in-frame') 50 if self.current: 51 rv.append('current') 52 return rv 53 54 classes = property(classes) 55 56 57 class Traceback(object): 58 59 def __init__(self, exc_type, exc_value, tb): 60 self.exc_type = exc_type 61 self.exc_value = exc_value 62 if not isinstance(exc_type, str): 63 exception_type = exc_type.__name__ 64 if exc_type.__module__ not in ('__builtin__', 'exceptions'): 65 exception_type = exc_type.__module__ + '.' + exception_type 66 else: 67 exception_type = exc_type 68 self.exception_type = exception_type 69 self.frames = [] 70 while tb: 71 self.frames.append(Frame(exc_type, exc_value, tb)) 72 tb = tb.tb_next 73 74 def filter_hidden_frames(self): 75 new_frames = [] 76 hidden = False 77 for frame in self.frames: 78 hide = frame.hide 79 if hide in ('before', 'before_and_this'): 80 new_frames = [] 81 hidden = False 82 if hide == 'before_and_this': 83 continue 84 elif hide in ('reset', 'reset_and_this'): 85 hidden = False 86 if hide == 'reset_and_this': 87 continue 88 elif hide in ('after', 'after_and_this'): 89 hidden = True 90 if hide == 'after_and_this': 91 continue 92 elif hide or hidden: 93 continue 94 new_frames.append(frame) 95 96 if self.frames[-1] in new_frames: 97 self.frames[:] = new_frames 98 99 def is_syntax_error(self): 100 return isinstance(self.exc_value, SyntaxError) 101 102 is_syntax_error = property(is_syntax_error) 103 104 def exception(self): 105 buf = traceback.format_exception_only(self.exc_type, self.exc_value) 106 return ''.join(buf).strip().decode('utf-8', 'replace') 107 108 exception = property(exception) 109 110 def log(self, logfile = None): 111 if logfile is None: 112 logfile = sys.stderr 113 tb = self.plaintext.encode('utf-8', 'replace').rstrip() + '\n' 114 logfile.write(tb) 115 116 def paste(self): 117 from xmlrpclib import ServerProxy 118 srv = ServerProxy('http://paste.pocoo.org/xmlrpc/') 119 return srv.pastes.newPaste('pytb', self.plaintext) 120 121 def render_summary(self, include_title = True): 122 return render_template('traceback_summary.html', traceback=self, include_title=include_title) 123 124 def render_full(self, evalex = False): 125 return render_template('traceback_full.html', traceback=self, evalex=evalex) 126 127 def plaintext(self): 128 return render_template('traceback_plaintext.html', traceback=self) 129 130 plaintext = cached_property(plaintext) 131 id = property(lambda x: id(x)) 132 133 134 class Frame(object): 135 136 def __init__(self, exc_type, exc_value, tb): 137 self.lineno = tb.tb_lineno 138 self.function_name = tb.tb_frame.f_code.co_name 139 self.locals = tb.tb_frame.f_locals 140 self.globals = tb.tb_frame.f_globals 141 fn = inspect.getsourcefile(tb) or inspect.getfile(tb) 142 if fn[-4:] in ('.pyo', '.pyc'): 143 fn = fn[:-1] 144 if os.path.isfile(fn): 145 fn = os.path.realpath(fn) 146 self.filename = fn 147 self.module = self.globals.get('__name__') 148 self.loader = self.globals.get('__loader__') 149 self.code = tb.tb_frame.f_code 150 self.hide = self.locals.get('__traceback_hide__', False) 151 info = self.locals.get('__traceback_info__') 152 if info is not None: 153 try: 154 info = unicode(info) 155 except UnicodeError: 156 info = str(info).decode('utf-8', 'replace') 157 158 self.info = info 159 160 def render(self): 161 return render_template('frame.html', frame=self) 162 163 def render_source(self): 164 lines = [ Line(idx + 1, x) for idx, x in enumerate(self.sourcelines) ] 165 if hasattr(self.code, 'co_firstlineno'): 166 lineno = self.code.co_firstlineno - 1 167 while lineno > 0: 168 if _funcdef_re.match(lines[lineno].code): 169 break 170 lineno -= 1 171 172 try: 173 offset = len(inspect.getblock([ x.code + '\n' for x in lines[lineno:] ])) 174 except TokenError: 175 offset = 0 176 177 for line in lines[lineno:lineno + offset]: 178 line.in_frame = True 179 180 try: 181 lines[self.lineno - 1].current = True 182 except IndexError: 183 pass 184 185 return render_template('source.html', frame=self, lines=lines) 186 187 def eval(self, code, mode = 'single'): 188 if isinstance(code, basestring): 189 if isinstance(code, unicode): 190 code = UTF8_COOKIE + code.encode('utf-8') 191 code = compile(code, '<interactive>', mode) 192 if mode != 'exec': 193 return eval(code, self.globals, self.locals) 194 exec code in self.globals, self.locals 195 196 @cached_property 197 def sourcelines(self): 198 source = None 199 if self.loader is not None: 200 try: 201 if hasattr(self.loader, 'get_source'): 202 source = self.loader.get_source(self.module) 203 elif hasattr(self.loader, 'get_source_by_code'): 204 source = self.loader.get_source_by_code(self.code) 205 except: 206 pass 207 208 if source is None: 209 try: 210 f = file(self.filename) 211 except IOError: 212 return [] 213 214 try: 215 source = f.read() 216 finally: 217 f.close() 218 219 if isinstance(source, unicode): 220 return source.splitlines() 221 charset = 'utf-8' 222 if source.startswith(UTF8_COOKIE): 223 source = source[3:] 224 else: 225 for idx, match in enumerate(_line_re.finditer(source)): 226 match = _line_re.search(match.group()) 227 if match is not None: 228 charset = match.group(1) 229 break 230 if idx > 1: 231 break 232 233 try: 234 codecs.lookup(charset) 235 except LookupError: 236 charset = 'utf-8' 237 238 return source.decode(charset, 'replace').splitlines() 239 240 @property 241 def current_line(self): 242 try: 243 return self.sourcelines[self.lineno - 1] 244 except IndexError: 245 return u'' 246 247 @cached_property 248 def console(self): 249 return Console(self.globals, self.locals) 250 251 id = property(lambda x: id(x))