NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

debug.py (7542B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\debug.py
      2 import sys
      3 import traceback
      4 from types import TracebackType
      5 from jinja2.utils import CodeType, missing, internal_code
      6 from jinja2.exceptions import TemplateSyntaxError
      7 try:
      8     from __pypy__ import tproxy
      9 except ImportError:
     10     tproxy = None
     11 
     12 try:
     13     exec "raise TypeError, 'foo'"
     14 except SyntaxError:
     15     raise_helper = 'raise __jinja_exception__[1]'
     16 except TypeError:
     17     raise_helper = 'raise __jinja_exception__[0], __jinja_exception__[1]'
     18 
     19 class TracebackFrameProxy(object):
     20 
     21     def __init__(self, tb):
     22         self.tb = tb
     23         self._tb_next = None
     24 
     25     @property
     26     def tb_next(self):
     27         return self._tb_next
     28 
     29     def set_next(self, next):
     30         if tb_set_next is not None:
     31             try:
     32                 tb_set_next(self.tb, next and next.tb or None)
     33             except Exception:
     34                 pass
     35 
     36         self._tb_next = next
     37 
     38     @property
     39     def is_jinja_frame(self):
     40         return '__jinja_template__' in self.tb.tb_frame.f_globals
     41 
     42     def __getattr__(self, name):
     43         return getattr(self.tb, name)
     44 
     45 
     46 def make_frame_proxy(frame):
     47     proxy = TracebackFrameProxy(frame)
     48     if tproxy is None:
     49         return proxy
     50 
     51     def operation_handler(operation, *args, **kwargs):
     52         if operation in ('__getattribute__', '__getattr__'):
     53             return getattr(proxy, args[0])
     54         if operation == '__setattr__':
     55             proxy.__setattr__(*args, **kwargs)
     56         else:
     57             return getattr(proxy, operation)(*args, **kwargs)
     58 
     59     return tproxy(TracebackType, operation_handler)
     60 
     61 
     62 class ProcessedTraceback(object):
     63 
     64     def __init__(self, exc_type, exc_value, frames):
     65         self.exc_type = exc_type
     66         self.exc_value = exc_value
     67         self.frames = frames
     68         prev_tb = None
     69         for tb in self.frames:
     70             if prev_tb is not None:
     71                 prev_tb.set_next(tb)
     72             prev_tb = tb
     73 
     74         prev_tb.set_next(None)
     75 
     76     def render_as_text(self, limit = None):
     77         lines = traceback.format_exception(self.exc_type, self.exc_value, self.frames[0], limit=limit)
     78         return ''.join(lines).rstrip()
     79 
     80     def render_as_html(self, full = False):
     81         from jinja2.debugrenderer import render_traceback
     82         return u'%s\n\n<!--\n%s\n-->' % (render_traceback(self, full=full), self.render_as_text().decode('utf-8', 'replace'))
     83 
     84     @property
     85     def is_template_syntax_error(self):
     86         return isinstance(self.exc_value, TemplateSyntaxError)
     87 
     88     @property
     89     def exc_info(self):
     90         return (self.exc_type, self.exc_value, self.frames[0])
     91 
     92     @property
     93     def standard_exc_info(self):
     94         tb = self.frames[0]
     95         if type(tb) is not TracebackType:
     96             tb = tb.tb
     97         return (self.exc_type, self.exc_value, tb)
     98 
     99 
    100 def make_traceback(exc_info, source_hint = None):
    101     exc_type, exc_value, tb = exc_info
    102     if isinstance(exc_value, TemplateSyntaxError):
    103         exc_info = translate_syntax_error(exc_value, source_hint)
    104         initial_skip = 0
    105     else:
    106         initial_skip = 1
    107     return translate_exception(exc_info, initial_skip)
    108 
    109 
    110 def translate_syntax_error(error, source = None):
    111     error.source = source
    112     error.translated = True
    113     exc_info = (error.__class__, error, None)
    114     filename = error.filename
    115     if filename is None:
    116         filename = '<unknown>'
    117     return fake_exc_info(exc_info, filename, error.lineno)
    118 
    119 
    120 def translate_exception(exc_info, initial_skip = 0):
    121     tb = exc_info[2]
    122     frames = []
    123     for x in xrange(initial_skip):
    124         if tb is not None:
    125             tb = tb.tb_next
    126 
    127     initial_tb = tb
    128     while tb is not None:
    129         if tb.tb_frame.f_code in internal_code:
    130             tb = tb.tb_next
    131             continue
    132         next = tb.tb_next
    133         template = tb.tb_frame.f_globals.get('__jinja_template__')
    134         if template is not None:
    135             lineno = template.get_corresponding_lineno(tb.tb_lineno)
    136             tb = fake_exc_info(exc_info[:2] + (tb,), template.filename, lineno)[2]
    137         frames.append(make_frame_proxy(tb))
    138         tb = next
    139 
    140     if not frames:
    141         raise exc_info[0], exc_info[1], exc_info[2]
    142     return ProcessedTraceback(exc_info[0], exc_info[1], frames)
    143 
    144 
    145 def fake_exc_info(exc_info, filename, lineno):
    146     exc_type, exc_value, tb = exc_info
    147     if tb is not None:
    148         real_locals = tb.tb_frame.f_locals.copy()
    149         ctx = real_locals.get('context')
    150         if ctx:
    151             locals = ctx.get_all()
    152         else:
    153             locals = {}
    154         for name, value in real_locals.iteritems():
    155             if name.startswith('l_') and value is not missing:
    156                 locals[name[2:]] = value
    157 
    158         locals.pop('__jinja_exception__', None)
    159     else:
    160         locals = {}
    161     globals = {'__name__': filename,
    162      '__file__': filename,
    163      '__jinja_exception__': exc_info[:2],
    164      '__jinja_template__': None}
    165     code = compile('\n' * (lineno - 1) + raise_helper, filename, 'exec')
    166     try:
    167         if tb is None:
    168             location = 'template'
    169         else:
    170             function = tb.tb_frame.f_code.co_name
    171             if function == 'root':
    172                 location = 'top-level template code'
    173             elif function.startswith('block_'):
    174                 location = 'block "%s"' % function[6:]
    175             else:
    176                 location = 'template'
    177         code = CodeType(0, code.co_nlocals, code.co_stacksize, code.co_flags, code.co_code, code.co_consts, code.co_names, code.co_varnames, filename, location, code.co_firstlineno, code.co_lnotab, (), ())
    178     except:
    179         pass
    180 
    181     try:
    182         exec code in globals, locals
    183     except:
    184         exc_info = sys.exc_info()
    185         new_tb = exc_info[2].tb_next
    186 
    187     return exc_info[:2] + (new_tb,)
    188 
    189 
    190 def _init_ugly_crap():
    191     import ctypes
    192     from types import TracebackType
    193     if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'):
    194         _Py_ssize_t = ctypes.c_int64
    195     else:
    196         _Py_ssize_t = ctypes.c_int
    197 
    198     class _PyObject(ctypes.Structure):
    199         pass
    200 
    201     _PyObject._fields_ = [('ob_refcnt', _Py_ssize_t), ('ob_type', ctypes.POINTER(_PyObject))]
    202     if hasattr(sys, 'getobjects'):
    203 
    204         class _PyObject(ctypes.Structure):
    205             pass
    206 
    207         _PyObject._fields_ = [('_ob_next', ctypes.POINTER(_PyObject)),
    208          ('_ob_prev', ctypes.POINTER(_PyObject)),
    209          ('ob_refcnt', _Py_ssize_t),
    210          ('ob_type', ctypes.POINTER(_PyObject))]
    211 
    212     class _Traceback(_PyObject):
    213         pass
    214 
    215     _Traceback._fields_ = [('tb_next', ctypes.POINTER(_Traceback)),
    216      ('tb_frame', ctypes.POINTER(_PyObject)),
    217      ('tb_lasti', ctypes.c_int),
    218      ('tb_lineno', ctypes.c_int)]
    219 
    220     def tb_set_next(tb, next):
    221         if not (isinstance(tb, TracebackType) and (next is None or isinstance(next, TracebackType))):
    222             raise TypeError('tb_set_next arguments must be traceback objects')
    223         obj = _Traceback.from_address(id(tb))
    224         if tb.tb_next is not None:
    225             old = _Traceback.from_address(id(tb.tb_next))
    226             old.ob_refcnt -= 1
    227         if next is None:
    228             obj.tb_next = ctypes.POINTER(_Traceback)()
    229         else:
    230             next = _Traceback.from_address(id(next))
    231             next.ob_refcnt += 1
    232             obj.tb_next = ctypes.pointer(next)
    233 
    234     return tb_set_next
    235 
    236 
    237 tb_set_next = None
    238 if tproxy is None:
    239     try:
    240         from jinja2._debugsupport import tb_set_next
    241     except ImportError:
    242         try:
    243             tb_set_next = _init_ugly_crap()
    244         except:
    245             pass
    246 
    247     del _init_ugly_crap