Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: third_party/jinja2/runtime.py

Issue 2316103002: binding: Updates Jinja2 from 2.7.1 to 2.8. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/jinja2/parser.py ('k') | third_party/jinja2/sandbox.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/jinja2/runtime.py
diff --git a/third_party/jinja2/runtime.py b/third_party/jinja2/runtime.py
index 7791c645afe997d45e75355fddad384f9d525d94..685a12da068c4808f2dfcec64d68e581f47e26fe 100644
--- a/third_party/jinja2/runtime.py
+++ b/third_party/jinja2/runtime.py
@@ -8,13 +8,15 @@
:copyright: (c) 2010 by the Jinja Team.
:license: BSD.
"""
+import sys
+
from itertools import chain
from jinja2.nodes import EvalContext, _context_function_types
from jinja2.utils import Markup, soft_unicode, escape, missing, concat, \
internalcode, object_type_repr
from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \
TemplateNotFound
-from jinja2._compat import next, imap, text_type, iteritems, \
+from jinja2._compat import imap, text_type, iteritems, \
implements_iterator, implements_to_string, string_types, PY2
@@ -22,7 +24,7 @@ from jinja2._compat import next, imap, text_type, iteritems, \
__all__ = ['LoopContext', 'TemplateReference', 'Macro', 'Markup',
'TemplateRuntimeError', 'missing', 'concat', 'escape',
'markup_join', 'unicode_join', 'to_string', 'identity',
- 'TemplateNotFound']
+ 'TemplateNotFound', 'make_logging_undefined']
#: the name of the function that is used to convert something into
#: a string. We can just use the text type here.
@@ -67,7 +69,8 @@ def new_context(environment, template_name, blocks, vars=None,
for key, value in iteritems(locals):
if key[:2] == 'l_' and value is not missing:
parent[key[2:]] = value
- return Context(environment, parent, template_name, blocks)
+ return environment.context_class(environment, parent, template_name,
+ blocks)
class TemplateReference(object):
@@ -171,7 +174,7 @@ class Context(object):
:func:`environmentfunction`.
"""
if __debug__:
- __traceback_hide__ = True
+ __traceback_hide__ = True # noqa
# Allow callable classes to take a context
fn = __obj.__call__
@@ -339,10 +342,11 @@ class LoopContext(object):
# if was not possible to get the length of the iterator when
# the loop context was created (ie: iterating over a generator)
# we have to convert the iterable into a sequence and use the
- # length of that.
+ # length of that + the number of iterations so far.
iterable = tuple(self._iterator)
self._iterator = iter(iterable)
- self._length = len(iterable) + self.index0 + 1
+ iterations_done = self.index0 + 2
+ self._length = len(iterable) + iterations_done
return self._length
def __repr__(self):
@@ -441,7 +445,7 @@ class Macro(object):
@implements_to_string
class Undefined(object):
"""The default undefined type. This undefined type can be printed and
- iterated over, but every other access will raise an :exc:`UndefinedError`:
+ iterated over, but every other access will raise an :exc:`jinja2.exceptions.UndefinedError`:
>>> foo = Undefined(name='foo')
>>> str(foo)
@@ -451,7 +455,7 @@ class Undefined(object):
>>> foo + 42
Traceback (most recent call last):
...
- UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = ('_undefined_hint', '_undefined_obj', '_undefined_name',
'_undefined_exception')
@@ -465,7 +469,7 @@ class Undefined(object):
@internalcode
def _fail_with_undefined_error(self, *args, **kwargs):
"""Regular callback function for undefined objects that raises an
- `UndefinedError` on call.
+ `jinja2.exceptions.UndefinedError` on call.
"""
if self._undefined_hint is None:
if self._undefined_obj is missing:
@@ -491,10 +495,10 @@ class Undefined(object):
return self._fail_with_undefined_error()
__add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \
- __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
- __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
- __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \
- __float__ = __complex__ = __pow__ = __rpow__ = \
+ __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \
+ __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \
+ __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \
+ __float__ = __complex__ = __pow__ = __rpow__ = \
_fail_with_undefined_error
def __eq__(self, other):
@@ -518,11 +522,93 @@ class Undefined(object):
def __nonzero__(self):
return False
+ __bool__ = __nonzero__
def __repr__(self):
return 'Undefined'
+def make_logging_undefined(logger=None, base=None):
+ """Given a logger object this returns a new undefined class that will
+ log certain failures. It will log iterations and printing. If no
+ logger is given a default logger is created.
+
+ Example::
+
+ logger = logging.getLogger(__name__)
+ LoggingUndefined = make_logging_undefined(
+ logger=logger,
+ base=Undefined
+ )
+
+ .. versionadded:: 2.8
+
+ :param logger: the logger to use. If not provided, a default logger
+ is created.
+ :param base: the base class to add logging functionality to. This
+ defaults to :class:`Undefined`.
+ """
+ if logger is None:
+ import logging
+ logger = logging.getLogger(__name__)
+ logger.addHandler(logging.StreamHandler(sys.stderr))
+ if base is None:
+ base = Undefined
+
+ def _log_message(undef):
+ if undef._undefined_hint is None:
+ if undef._undefined_obj is missing:
+ hint = '%s is undefined' % undef._undefined_name
+ elif not isinstance(undef._undefined_name, string_types):
+ hint = '%s has no element %s' % (
+ object_type_repr(undef._undefined_obj),
+ undef._undefined_name)
+ else:
+ hint = '%s has no attribute %s' % (
+ object_type_repr(undef._undefined_obj),
+ undef._undefined_name)
+ else:
+ hint = undef._undefined_hint
+ logger.warning('Template variable warning: %s', hint)
+
+ class LoggingUndefined(base):
+
+ def _fail_with_undefined_error(self, *args, **kwargs):
+ try:
+ return base._fail_with_undefined_error(self, *args, **kwargs)
+ except self._undefined_exception as e:
+ logger.error('Template variable error: %s', str(e))
+ raise e
+
+ def __str__(self):
+ rv = base.__str__(self)
+ _log_message(self)
+ return rv
+
+ def __iter__(self):
+ rv = base.__iter__(self)
+ _log_message(self)
+ return rv
+
+ if PY2:
+ def __nonzero__(self):
+ rv = base.__nonzero__(self)
+ _log_message(self)
+ return rv
+
+ def __unicode__(self):
+ rv = base.__unicode__(self)
+ _log_message(self)
+ return rv
+ else:
+ def __bool__(self):
+ rv = base.__bool__(self)
+ _log_message(self)
+ return rv
+
+ return LoggingUndefined
+
+
@implements_to_string
class DebugUndefined(Undefined):
"""An undefined that returns the debug info when printed.
@@ -535,7 +621,7 @@ class DebugUndefined(Undefined):
>>> foo + 42
Traceback (most recent call last):
...
- UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = ()
@@ -560,15 +646,15 @@ class StrictUndefined(Undefined):
>>> str(foo)
Traceback (most recent call last):
...
- UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> not foo
Traceback (most recent call last):
...
- UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> foo + 42
Traceback (most recent call last):
...
- UndefinedError: 'foo' is undefined
+ jinja2.exceptions.UndefinedError: 'foo' is undefined
"""
__slots__ = ()
__iter__ = __str__ = __len__ = __nonzero__ = __eq__ = \
« no previous file with comments | « third_party/jinja2/parser.py ('k') | third_party/jinja2/sandbox.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698