Package asmach :: Module tb_edit

Source Code for Module asmach.tb_edit

 1  # -*- coding: utf-8 -*- 
 2  """ 
 3      jinja2.debug 
 4      ~~~~~~~~~~~~ 
 5   
 6      Implements the debug interface for Jinja.  This module does some pretty 
 7      ugly stuff with the Python traceback system in order to achieve tracebacks 
 8      with correct line numbers, locals and contents. 
 9   
10      :copyright: (c) 2010 by the Jinja Team. 
11      :license: BSD, see LICENSE for more details. 
12  """ 
13  import sys 
14  import traceback 
15   
16 -def _init_ugly_crap():
17 """This function implements a few ugly things so that we can patch the 18 traceback objects. The function returned allows resetting `tb_next` on 19 any python traceback object. 20 """ 21 import ctypes 22 from types import TracebackType 23 24 # figure out side of _Py_ssize_t 25 if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'): 26 _Py_ssize_t = ctypes.c_int64 27 else: 28 _Py_ssize_t = ctypes.c_int 29 30 # regular python 31 class _PyObject(ctypes.Structure): 32 pass
33 _PyObject._fields_ = [ 34 ('ob_refcnt', _Py_ssize_t), 35 ('ob_type', ctypes.POINTER(_PyObject)) 36 ] 37 38 # python with trace 39 if object.__basicsize__ != ctypes.sizeof(_PyObject): 40 class _PyObject(ctypes.Structure): 41 pass 42 _PyObject._fields_ = [ 43 ('_ob_next', ctypes.POINTER(_PyObject)), 44 ('_ob_prev', ctypes.POINTER(_PyObject)), 45 ('ob_refcnt', _Py_ssize_t), 46 ('ob_type', ctypes.POINTER(_PyObject)) 47 ] 48 49 class _Traceback(_PyObject): 50 pass 51 _Traceback._fields_ = [ 52 ('tb_next', ctypes.POINTER(_Traceback)), 53 ('tb_frame', ctypes.POINTER(_PyObject)), 54 ('tb_lasti', ctypes.c_int), 55 ('tb_lineno', ctypes.c_int) 56 ] 57 58 def tb_set_next(tb, next): 59 """Set the tb_next attribute of a traceback object.""" 60 if not (isinstance(tb, TracebackType) and 61 (next is None or isinstance(next, TracebackType))): 62 raise TypeError('tb_set_next arguments must be traceback objects') 63 obj = _Traceback.from_address(id(tb)) 64 if tb.tb_next is not None: 65 old = _Traceback.from_address(id(tb.tb_next)) 66 old.ob_refcnt -= 1 67 if next is None: 68 obj.tb_next = ctypes.POINTER(_Traceback)() 69 else: 70 next = _Traceback.from_address(id(next)) 71 next.ob_refcnt += 1 72 obj.tb_next = ctypes.pointer(next) 73 74 return tb_set_next 75 76 77 # try to get a tb_set_next implementation 78 try: 79 tb_set_next = _init_ugly_crap() 80 except: 81 tb_set_next = None 82 del _init_ugly_crap 83