| OLD | NEW |
| 1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
| 2 """ | 2 """ |
| 3 jinja2.debug | 3 jinja2.debug |
| 4 ~~~~~~~~~~~~ | 4 ~~~~~~~~~~~~ |
| 5 | 5 |
| 6 Implements the debug interface for Jinja. This module does some pretty | 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 | 7 ugly stuff with the Python traceback system in order to achieve tracebacks |
| 8 with correct line numbers, locals and contents. | 8 with correct line numbers, locals and contents. |
| 9 | 9 |
| 10 :copyright: (c) 2010 by the Jinja Team. | 10 :copyright: (c) 2010 by the Jinja Team. |
| 11 :license: BSD, see LICENSE for more details. | 11 :license: BSD, see LICENSE for more details. |
| 12 """ | 12 """ |
| 13 import sys | 13 import sys |
| 14 import traceback | 14 import traceback |
| 15 from types import TracebackType | 15 from types import TracebackType, CodeType |
| 16 from jinja2.utils import missing, internal_code | 16 from jinja2.utils import missing, internal_code |
| 17 from jinja2.exceptions import TemplateSyntaxError | 17 from jinja2.exceptions import TemplateSyntaxError |
| 18 from jinja2._compat import iteritems, reraise, code_type | 18 from jinja2._compat import iteritems, reraise, PY2 |
| 19 | 19 |
| 20 # on pypy we can take advantage of transparent proxies | 20 # on pypy we can take advantage of transparent proxies |
| 21 try: | 21 try: |
| 22 from __pypy__ import tproxy | 22 from __pypy__ import tproxy |
| 23 except ImportError: | 23 except ImportError: |
| 24 tproxy = None | 24 tproxy = None |
| 25 | 25 |
| 26 | 26 |
| 27 # how does the raise helper look like? | 27 # how does the raise helper look like? |
| 28 try: | 28 try: |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 if tb is None: | 238 if tb is None: |
| 239 location = 'template' | 239 location = 'template' |
| 240 else: | 240 else: |
| 241 function = tb.tb_frame.f_code.co_name | 241 function = tb.tb_frame.f_code.co_name |
| 242 if function == 'root': | 242 if function == 'root': |
| 243 location = 'top-level template code' | 243 location = 'top-level template code' |
| 244 elif function.startswith('block_'): | 244 elif function.startswith('block_'): |
| 245 location = 'block "%s"' % function[6:] | 245 location = 'block "%s"' % function[6:] |
| 246 else: | 246 else: |
| 247 location = 'template' | 247 location = 'template' |
| 248 code = code_type(0, code.co_nlocals, code.co_stacksize, | 248 |
| 249 code.co_flags, code.co_code, code.co_consts, | 249 if PY2: |
| 250 code.co_names, code.co_varnames, filename, | 250 code = CodeType(0, code.co_nlocals, code.co_stacksize, |
| 251 location, code.co_firstlineno, | 251 code.co_flags, code.co_code, code.co_consts, |
| 252 code.co_lnotab, (), ()) | 252 code.co_names, code.co_varnames, filename, |
| 253 except: | 253 location, code.co_firstlineno, |
| 254 code.co_lnotab, (), ()) |
| 255 else: |
| 256 code = CodeType(0, code.co_kwonlyargcount, |
| 257 code.co_nlocals, code.co_stacksize, |
| 258 code.co_flags, code.co_code, code.co_consts, |
| 259 code.co_names, code.co_varnames, filename, |
| 260 location, code.co_firstlineno, |
| 261 code.co_lnotab, (), ()) |
| 262 except Exception as e: |
| 254 pass | 263 pass |
| 255 | 264 |
| 256 # execute the code and catch the new traceback | 265 # execute the code and catch the new traceback |
| 257 try: | 266 try: |
| 258 exec(code, globals, locals) | 267 exec(code, globals, locals) |
| 259 except: | 268 except: |
| 260 exc_info = sys.exc_info() | 269 exc_info = sys.exc_info() |
| 261 new_tb = exc_info[2].tb_next | 270 new_tb = exc_info[2].tb_next |
| 262 | 271 |
| 263 # return without this frame | 272 # return without this frame |
| 264 return exc_info[:2] + (new_tb,) | 273 return exc_info[:2] + (new_tb,) |
| 265 | 274 |
| 266 | 275 |
| 267 def _init_ugly_crap(): | 276 def _init_ugly_crap(): |
| 268 """This function implements a few ugly things so that we can patch the | 277 """This function implements a few ugly things so that we can patch the |
| 269 traceback objects. The function returned allows resetting `tb_next` on | 278 traceback objects. The function returned allows resetting `tb_next` on |
| 270 any python traceback object. Do not attempt to use this on non cpython | 279 any python traceback object. Do not attempt to use this on non cpython |
| 271 interpreters | 280 interpreters |
| 272 """ | 281 """ |
| 273 import ctypes | 282 import ctypes |
| 274 from types import TracebackType | 283 from types import TracebackType |
| 275 | 284 |
| 276 # figure out side of _Py_ssize_t | 285 if PY2: |
| 277 if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'): | 286 # figure out size of _Py_ssize_t for Python 2: |
| 278 _Py_ssize_t = ctypes.c_int64 | 287 if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'): |
| 288 _Py_ssize_t = ctypes.c_int64 |
| 289 else: |
| 290 _Py_ssize_t = ctypes.c_int |
| 279 else: | 291 else: |
| 280 _Py_ssize_t = ctypes.c_int | 292 # platform ssize_t on Python 3 |
| 293 _Py_ssize_t = ctypes.c_ssize_t |
| 281 | 294 |
| 282 # regular python | 295 # regular python |
| 283 class _PyObject(ctypes.Structure): | 296 class _PyObject(ctypes.Structure): |
| 284 pass | 297 pass |
| 285 _PyObject._fields_ = [ | 298 _PyObject._fields_ = [ |
| 286 ('ob_refcnt', _Py_ssize_t), | 299 ('ob_refcnt', _Py_ssize_t), |
| 287 ('ob_type', ctypes.POINTER(_PyObject)) | 300 ('ob_type', ctypes.POINTER(_PyObject)) |
| 288 ] | 301 ] |
| 289 | 302 |
| 290 # python with trace | 303 # python with trace |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 | 341 |
| 329 # try to get a tb_set_next implementation if we don't have transparent | 342 # try to get a tb_set_next implementation if we don't have transparent |
| 330 # proxies. | 343 # proxies. |
| 331 tb_set_next = None | 344 tb_set_next = None |
| 332 if tproxy is None: | 345 if tproxy is None: |
| 333 try: | 346 try: |
| 334 tb_set_next = _init_ugly_crap() | 347 tb_set_next = _init_ugly_crap() |
| 335 except: | 348 except: |
| 336 pass | 349 pass |
| 337 del _init_ugly_crap | 350 del _init_ugly_crap |
| OLD | NEW |