| Index: mojo/public/third_party/jinja2/debug.py
|
| diff --git a/mojo/public/third_party/jinja2/debug.py b/mojo/public/third_party/jinja2/debug.py
|
| deleted file mode 100644
|
| index 815cc18a4f8fd76e747835f24c1297a7d2264628..0000000000000000000000000000000000000000
|
| --- a/mojo/public/third_party/jinja2/debug.py
|
| +++ /dev/null
|
| @@ -1,337 +0,0 @@
|
| -# -*- coding: utf-8 -*-
|
| -"""
|
| - jinja2.debug
|
| - ~~~~~~~~~~~~
|
| -
|
| - Implements the debug interface for Jinja. This module does some pretty
|
| - ugly stuff with the Python traceback system in order to achieve tracebacks
|
| - with correct line numbers, locals and contents.
|
| -
|
| - :copyright: (c) 2010 by the Jinja Team.
|
| - :license: BSD, see LICENSE for more details.
|
| -"""
|
| -import sys
|
| -import traceback
|
| -from types import TracebackType
|
| -from jinja2.utils import missing, internal_code
|
| -from jinja2.exceptions import TemplateSyntaxError
|
| -from jinja2._compat import iteritems, reraise, code_type
|
| -
|
| -# on pypy we can take advantage of transparent proxies
|
| -try:
|
| - from __pypy__ import tproxy
|
| -except ImportError:
|
| - tproxy = None
|
| -
|
| -
|
| -# how does the raise helper look like?
|
| -try:
|
| - exec("raise TypeError, 'foo'")
|
| -except SyntaxError:
|
| - raise_helper = 'raise __jinja_exception__[1]'
|
| -except TypeError:
|
| - raise_helper = 'raise __jinja_exception__[0], __jinja_exception__[1]'
|
| -
|
| -
|
| -class TracebackFrameProxy(object):
|
| - """Proxies a traceback frame."""
|
| -
|
| - def __init__(self, tb):
|
| - self.tb = tb
|
| - self._tb_next = None
|
| -
|
| - @property
|
| - def tb_next(self):
|
| - return self._tb_next
|
| -
|
| - def set_next(self, next):
|
| - if tb_set_next is not None:
|
| - try:
|
| - tb_set_next(self.tb, next and next.tb or None)
|
| - except Exception:
|
| - # this function can fail due to all the hackery it does
|
| - # on various python implementations. We just catch errors
|
| - # down and ignore them if necessary.
|
| - pass
|
| - self._tb_next = next
|
| -
|
| - @property
|
| - def is_jinja_frame(self):
|
| - return '__jinja_template__' in self.tb.tb_frame.f_globals
|
| -
|
| - def __getattr__(self, name):
|
| - return getattr(self.tb, name)
|
| -
|
| -
|
| -def make_frame_proxy(frame):
|
| - proxy = TracebackFrameProxy(frame)
|
| - if tproxy is None:
|
| - return proxy
|
| - def operation_handler(operation, *args, **kwargs):
|
| - if operation in ('__getattribute__', '__getattr__'):
|
| - return getattr(proxy, args[0])
|
| - elif operation == '__setattr__':
|
| - proxy.__setattr__(*args, **kwargs)
|
| - else:
|
| - return getattr(proxy, operation)(*args, **kwargs)
|
| - return tproxy(TracebackType, operation_handler)
|
| -
|
| -
|
| -class ProcessedTraceback(object):
|
| - """Holds a Jinja preprocessed traceback for printing or reraising."""
|
| -
|
| - def __init__(self, exc_type, exc_value, frames):
|
| - assert frames, 'no frames for this traceback?'
|
| - self.exc_type = exc_type
|
| - self.exc_value = exc_value
|
| - self.frames = frames
|
| -
|
| - # newly concatenate the frames (which are proxies)
|
| - prev_tb = None
|
| - for tb in self.frames:
|
| - if prev_tb is not None:
|
| - prev_tb.set_next(tb)
|
| - prev_tb = tb
|
| - prev_tb.set_next(None)
|
| -
|
| - def render_as_text(self, limit=None):
|
| - """Return a string with the traceback."""
|
| - lines = traceback.format_exception(self.exc_type, self.exc_value,
|
| - self.frames[0], limit=limit)
|
| - return ''.join(lines).rstrip()
|
| -
|
| - def render_as_html(self, full=False):
|
| - """Return a unicode string with the traceback as rendered HTML."""
|
| - from jinja2.debugrenderer import render_traceback
|
| - return u'%s\n\n<!--\n%s\n-->' % (
|
| - render_traceback(self, full=full),
|
| - self.render_as_text().decode('utf-8', 'replace')
|
| - )
|
| -
|
| - @property
|
| - def is_template_syntax_error(self):
|
| - """`True` if this is a template syntax error."""
|
| - return isinstance(self.exc_value, TemplateSyntaxError)
|
| -
|
| - @property
|
| - def exc_info(self):
|
| - """Exception info tuple with a proxy around the frame objects."""
|
| - return self.exc_type, self.exc_value, self.frames[0]
|
| -
|
| - @property
|
| - def standard_exc_info(self):
|
| - """Standard python exc_info for re-raising"""
|
| - tb = self.frames[0]
|
| - # the frame will be an actual traceback (or transparent proxy) if
|
| - # we are on pypy or a python implementation with support for tproxy
|
| - if type(tb) is not TracebackType:
|
| - tb = tb.tb
|
| - return self.exc_type, self.exc_value, tb
|
| -
|
| -
|
| -def make_traceback(exc_info, source_hint=None):
|
| - """Creates a processed traceback object from the exc_info."""
|
| - exc_type, exc_value, tb = exc_info
|
| - if isinstance(exc_value, TemplateSyntaxError):
|
| - exc_info = translate_syntax_error(exc_value, source_hint)
|
| - initial_skip = 0
|
| - else:
|
| - initial_skip = 1
|
| - return translate_exception(exc_info, initial_skip)
|
| -
|
| -
|
| -def translate_syntax_error(error, source=None):
|
| - """Rewrites a syntax error to please traceback systems."""
|
| - error.source = source
|
| - error.translated = True
|
| - exc_info = (error.__class__, error, None)
|
| - filename = error.filename
|
| - if filename is None:
|
| - filename = '<unknown>'
|
| - return fake_exc_info(exc_info, filename, error.lineno)
|
| -
|
| -
|
| -def translate_exception(exc_info, initial_skip=0):
|
| - """If passed an exc_info it will automatically rewrite the exceptions
|
| - all the way down to the correct line numbers and frames.
|
| - """
|
| - tb = exc_info[2]
|
| - frames = []
|
| -
|
| - # skip some internal frames if wanted
|
| - for x in range(initial_skip):
|
| - if tb is not None:
|
| - tb = tb.tb_next
|
| - initial_tb = tb
|
| -
|
| - while tb is not None:
|
| - # skip frames decorated with @internalcode. These are internal
|
| - # calls we can't avoid and that are useless in template debugging
|
| - # output.
|
| - if tb.tb_frame.f_code in internal_code:
|
| - tb = tb.tb_next
|
| - continue
|
| -
|
| - # save a reference to the next frame if we override the current
|
| - # one with a faked one.
|
| - next = tb.tb_next
|
| -
|
| - # fake template exceptions
|
| - template = tb.tb_frame.f_globals.get('__jinja_template__')
|
| - if template is not None:
|
| - lineno = template.get_corresponding_lineno(tb.tb_lineno)
|
| - tb = fake_exc_info(exc_info[:2] + (tb,), template.filename,
|
| - lineno)[2]
|
| -
|
| - frames.append(make_frame_proxy(tb))
|
| - tb = next
|
| -
|
| - # if we don't have any exceptions in the frames left, we have to
|
| - # reraise it unchanged.
|
| - # XXX: can we backup here? when could this happen?
|
| - if not frames:
|
| - reraise(exc_info[0], exc_info[1], exc_info[2])
|
| -
|
| - return ProcessedTraceback(exc_info[0], exc_info[1], frames)
|
| -
|
| -
|
| -def fake_exc_info(exc_info, filename, lineno):
|
| - """Helper for `translate_exception`."""
|
| - exc_type, exc_value, tb = exc_info
|
| -
|
| - # figure the real context out
|
| - if tb is not None:
|
| - real_locals = tb.tb_frame.f_locals.copy()
|
| - ctx = real_locals.get('context')
|
| - if ctx:
|
| - locals = ctx.get_all()
|
| - else:
|
| - locals = {}
|
| - for name, value in iteritems(real_locals):
|
| - if name.startswith('l_') and value is not missing:
|
| - locals[name[2:]] = value
|
| -
|
| - # if there is a local called __jinja_exception__, we get
|
| - # rid of it to not break the debug functionality.
|
| - locals.pop('__jinja_exception__', None)
|
| - else:
|
| - locals = {}
|
| -
|
| - # assamble fake globals we need
|
| - globals = {
|
| - '__name__': filename,
|
| - '__file__': filename,
|
| - '__jinja_exception__': exc_info[:2],
|
| -
|
| - # we don't want to keep the reference to the template around
|
| - # to not cause circular dependencies, but we mark it as Jinja
|
| - # frame for the ProcessedTraceback
|
| - '__jinja_template__': None
|
| - }
|
| -
|
| - # and fake the exception
|
| - code = compile('\n' * (lineno - 1) + raise_helper, filename, 'exec')
|
| -
|
| - # if it's possible, change the name of the code. This won't work
|
| - # on some python environments such as google appengine
|
| - try:
|
| - if tb is None:
|
| - location = 'template'
|
| - else:
|
| - function = tb.tb_frame.f_code.co_name
|
| - if function == 'root':
|
| - location = 'top-level template code'
|
| - elif function.startswith('block_'):
|
| - location = 'block "%s"' % function[6:]
|
| - else:
|
| - location = 'template'
|
| - code = code_type(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, (), ())
|
| - except:
|
| - pass
|
| -
|
| - # execute the code and catch the new traceback
|
| - try:
|
| - exec(code, globals, locals)
|
| - except:
|
| - exc_info = sys.exc_info()
|
| - new_tb = exc_info[2].tb_next
|
| -
|
| - # return without this frame
|
| - return exc_info[:2] + (new_tb,)
|
| -
|
| -
|
| -def _init_ugly_crap():
|
| - """This function implements a few ugly things so that we can patch the
|
| - traceback objects. The function returned allows resetting `tb_next` on
|
| - any python traceback object. Do not attempt to use this on non cpython
|
| - interpreters
|
| - """
|
| - import ctypes
|
| - from types import TracebackType
|
| -
|
| - # figure out side of _Py_ssize_t
|
| - if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'):
|
| - _Py_ssize_t = ctypes.c_int64
|
| - else:
|
| - _Py_ssize_t = ctypes.c_int
|
| -
|
| - # regular python
|
| - class _PyObject(ctypes.Structure):
|
| - pass
|
| - _PyObject._fields_ = [
|
| - ('ob_refcnt', _Py_ssize_t),
|
| - ('ob_type', ctypes.POINTER(_PyObject))
|
| - ]
|
| -
|
| - # python with trace
|
| - if hasattr(sys, 'getobjects'):
|
| - class _PyObject(ctypes.Structure):
|
| - pass
|
| - _PyObject._fields_ = [
|
| - ('_ob_next', ctypes.POINTER(_PyObject)),
|
| - ('_ob_prev', ctypes.POINTER(_PyObject)),
|
| - ('ob_refcnt', _Py_ssize_t),
|
| - ('ob_type', ctypes.POINTER(_PyObject))
|
| - ]
|
| -
|
| - class _Traceback(_PyObject):
|
| - pass
|
| - _Traceback._fields_ = [
|
| - ('tb_next', ctypes.POINTER(_Traceback)),
|
| - ('tb_frame', ctypes.POINTER(_PyObject)),
|
| - ('tb_lasti', ctypes.c_int),
|
| - ('tb_lineno', ctypes.c_int)
|
| - ]
|
| -
|
| - def tb_set_next(tb, next):
|
| - """Set the tb_next attribute of a traceback object."""
|
| - if not (isinstance(tb, TracebackType) and
|
| - (next is None or isinstance(next, TracebackType))):
|
| - raise TypeError('tb_set_next arguments must be traceback objects')
|
| - obj = _Traceback.from_address(id(tb))
|
| - if tb.tb_next is not None:
|
| - old = _Traceback.from_address(id(tb.tb_next))
|
| - old.ob_refcnt -= 1
|
| - if next is None:
|
| - obj.tb_next = ctypes.POINTER(_Traceback)()
|
| - else:
|
| - next = _Traceback.from_address(id(next))
|
| - next.ob_refcnt += 1
|
| - obj.tb_next = ctypes.pointer(next)
|
| -
|
| - return tb_set_next
|
| -
|
| -
|
| -# try to get a tb_set_next implementation if we don't have transparent
|
| -# proxies.
|
| -tb_set_next = None
|
| -if tproxy is None:
|
| - try:
|
| - tb_set_next = _init_ugly_crap()
|
| - except:
|
| - pass
|
| - del _init_ugly_crap
|
|
|