Index: mojo/public/third_party/jinja2/runtime.py |
diff --git a/mojo/public/third_party/jinja2/runtime.py b/mojo/public/third_party/jinja2/runtime.py |
deleted file mode 100644 |
index 7791c645afe997d45e75355fddad384f9d525d94..0000000000000000000000000000000000000000 |
--- a/mojo/public/third_party/jinja2/runtime.py |
+++ /dev/null |
@@ -1,581 +0,0 @@ |
-# -*- coding: utf-8 -*- |
-""" |
- jinja2.runtime |
- ~~~~~~~~~~~~~~ |
- |
- Runtime helpers. |
- |
- :copyright: (c) 2010 by the Jinja Team. |
- :license: BSD. |
-""" |
-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, \ |
- implements_iterator, implements_to_string, string_types, PY2 |
- |
- |
-# these variables are exported to the template runtime |
-__all__ = ['LoopContext', 'TemplateReference', 'Macro', 'Markup', |
- 'TemplateRuntimeError', 'missing', 'concat', 'escape', |
- 'markup_join', 'unicode_join', 'to_string', 'identity', |
- 'TemplateNotFound'] |
- |
-#: the name of the function that is used to convert something into |
-#: a string. We can just use the text type here. |
-to_string = text_type |
- |
-#: the identity function. Useful for certain things in the environment |
-identity = lambda x: x |
- |
-_last_iteration = object() |
- |
- |
-def markup_join(seq): |
- """Concatenation that escapes if necessary and converts to unicode.""" |
- buf = [] |
- iterator = imap(soft_unicode, seq) |
- for arg in iterator: |
- buf.append(arg) |
- if hasattr(arg, '__html__'): |
- return Markup(u'').join(chain(buf, iterator)) |
- return concat(buf) |
- |
- |
-def unicode_join(seq): |
- """Simple args to unicode conversion and concatenation.""" |
- return concat(imap(text_type, seq)) |
- |
- |
-def new_context(environment, template_name, blocks, vars=None, |
- shared=None, globals=None, locals=None): |
- """Internal helper to for context creation.""" |
- if vars is None: |
- vars = {} |
- if shared: |
- parent = vars |
- else: |
- parent = dict(globals or (), **vars) |
- if locals: |
- # if the parent is shared a copy should be created because |
- # we don't want to modify the dict passed |
- if shared: |
- parent = dict(parent) |
- 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) |
- |
- |
-class TemplateReference(object): |
- """The `self` in templates.""" |
- |
- def __init__(self, context): |
- self.__context = context |
- |
- def __getitem__(self, name): |
- blocks = self.__context.blocks[name] |
- return BlockReference(name, self.__context, blocks, 0) |
- |
- def __repr__(self): |
- return '<%s %r>' % ( |
- self.__class__.__name__, |
- self.__context.name |
- ) |
- |
- |
-class Context(object): |
- """The template context holds the variables of a template. It stores the |
- values passed to the template and also the names the template exports. |
- Creating instances is neither supported nor useful as it's created |
- automatically at various stages of the template evaluation and should not |
- be created by hand. |
- |
- The context is immutable. Modifications on :attr:`parent` **must not** |
- happen and modifications on :attr:`vars` are allowed from generated |
- template code only. Template filters and global functions marked as |
- :func:`contextfunction`\s get the active context passed as first argument |
- and are allowed to access the context read-only. |
- |
- The template context supports read only dict operations (`get`, |
- `keys`, `values`, `items`, `iterkeys`, `itervalues`, `iteritems`, |
- `__getitem__`, `__contains__`). Additionally there is a :meth:`resolve` |
- method that doesn't fail with a `KeyError` but returns an |
- :class:`Undefined` object for missing variables. |
- """ |
- __slots__ = ('parent', 'vars', 'environment', 'eval_ctx', 'exported_vars', |
- 'name', 'blocks', '__weakref__') |
- |
- def __init__(self, environment, parent, name, blocks): |
- self.parent = parent |
- self.vars = {} |
- self.environment = environment |
- self.eval_ctx = EvalContext(self.environment, name) |
- self.exported_vars = set() |
- self.name = name |
- |
- # create the initial mapping of blocks. Whenever template inheritance |
- # takes place the runtime will update this mapping with the new blocks |
- # from the template. |
- self.blocks = dict((k, [v]) for k, v in iteritems(blocks)) |
- |
- def super(self, name, current): |
- """Render a parent block.""" |
- try: |
- blocks = self.blocks[name] |
- index = blocks.index(current) + 1 |
- blocks[index] |
- except LookupError: |
- return self.environment.undefined('there is no parent block ' |
- 'called %r.' % name, |
- name='super') |
- return BlockReference(name, self, blocks, index) |
- |
- def get(self, key, default=None): |
- """Returns an item from the template context, if it doesn't exist |
- `default` is returned. |
- """ |
- try: |
- return self[key] |
- except KeyError: |
- return default |
- |
- def resolve(self, key): |
- """Looks up a variable like `__getitem__` or `get` but returns an |
- :class:`Undefined` object with the name of the name looked up. |
- """ |
- if key in self.vars: |
- return self.vars[key] |
- if key in self.parent: |
- return self.parent[key] |
- return self.environment.undefined(name=key) |
- |
- def get_exported(self): |
- """Get a new dict with the exported variables.""" |
- return dict((k, self.vars[k]) for k in self.exported_vars) |
- |
- def get_all(self): |
- """Return a copy of the complete context as dict including the |
- exported variables. |
- """ |
- return dict(self.parent, **self.vars) |
- |
- @internalcode |
- def call(__self, __obj, *args, **kwargs): |
- """Call the callable with the arguments and keyword arguments |
- provided but inject the active context or environment as first |
- argument if the callable is a :func:`contextfunction` or |
- :func:`environmentfunction`. |
- """ |
- if __debug__: |
- __traceback_hide__ = True |
- |
- # Allow callable classes to take a context |
- fn = __obj.__call__ |
- for fn_type in ('contextfunction', |
- 'evalcontextfunction', |
- 'environmentfunction'): |
- if hasattr(fn, fn_type): |
- __obj = fn |
- break |
- |
- if isinstance(__obj, _context_function_types): |
- if getattr(__obj, 'contextfunction', 0): |
- args = (__self,) + args |
- elif getattr(__obj, 'evalcontextfunction', 0): |
- args = (__self.eval_ctx,) + args |
- elif getattr(__obj, 'environmentfunction', 0): |
- args = (__self.environment,) + args |
- try: |
- return __obj(*args, **kwargs) |
- except StopIteration: |
- return __self.environment.undefined('value was undefined because ' |
- 'a callable raised a ' |
- 'StopIteration exception') |
- |
- def derived(self, locals=None): |
- """Internal helper function to create a derived context.""" |
- context = new_context(self.environment, self.name, {}, |
- self.parent, True, None, locals) |
- context.vars.update(self.vars) |
- context.eval_ctx = self.eval_ctx |
- context.blocks.update((k, list(v)) for k, v in iteritems(self.blocks)) |
- return context |
- |
- def _all(meth): |
- proxy = lambda self: getattr(self.get_all(), meth)() |
- proxy.__doc__ = getattr(dict, meth).__doc__ |
- proxy.__name__ = meth |
- return proxy |
- |
- keys = _all('keys') |
- values = _all('values') |
- items = _all('items') |
- |
- # not available on python 3 |
- if PY2: |
- iterkeys = _all('iterkeys') |
- itervalues = _all('itervalues') |
- iteritems = _all('iteritems') |
- del _all |
- |
- def __contains__(self, name): |
- return name in self.vars or name in self.parent |
- |
- def __getitem__(self, key): |
- """Lookup a variable or raise `KeyError` if the variable is |
- undefined. |
- """ |
- item = self.resolve(key) |
- if isinstance(item, Undefined): |
- raise KeyError(key) |
- return item |
- |
- def __repr__(self): |
- return '<%s %s of %r>' % ( |
- self.__class__.__name__, |
- repr(self.get_all()), |
- self.name |
- ) |
- |
- |
-# register the context as mapping if possible |
-try: |
- from collections import Mapping |
- Mapping.register(Context) |
-except ImportError: |
- pass |
- |
- |
-class BlockReference(object): |
- """One block on a template reference.""" |
- |
- def __init__(self, name, context, stack, depth): |
- self.name = name |
- self._context = context |
- self._stack = stack |
- self._depth = depth |
- |
- @property |
- def super(self): |
- """Super the block.""" |
- if self._depth + 1 >= len(self._stack): |
- return self._context.environment. \ |
- undefined('there is no parent block called %r.' % |
- self.name, name='super') |
- return BlockReference(self.name, self._context, self._stack, |
- self._depth + 1) |
- |
- @internalcode |
- def __call__(self): |
- rv = concat(self._stack[self._depth](self._context)) |
- if self._context.eval_ctx.autoescape: |
- rv = Markup(rv) |
- return rv |
- |
- |
-class LoopContext(object): |
- """A loop context for dynamic iteration.""" |
- |
- def __init__(self, iterable, recurse=None, depth0=0): |
- self._iterator = iter(iterable) |
- self._recurse = recurse |
- self._after = self._safe_next() |
- self.index0 = -1 |
- self.depth0 = depth0 |
- |
- # try to get the length of the iterable early. This must be done |
- # here because there are some broken iterators around where there |
- # __len__ is the number of iterations left (i'm looking at your |
- # listreverseiterator!). |
- try: |
- self._length = len(iterable) |
- except (TypeError, AttributeError): |
- self._length = None |
- |
- def cycle(self, *args): |
- """Cycles among the arguments with the current loop index.""" |
- if not args: |
- raise TypeError('no items for cycling given') |
- return args[self.index0 % len(args)] |
- |
- first = property(lambda x: x.index0 == 0) |
- last = property(lambda x: x._after is _last_iteration) |
- index = property(lambda x: x.index0 + 1) |
- revindex = property(lambda x: x.length - x.index0) |
- revindex0 = property(lambda x: x.length - x.index) |
- depth = property(lambda x: x.depth0 + 1) |
- |
- def __len__(self): |
- return self.length |
- |
- def __iter__(self): |
- return LoopContextIterator(self) |
- |
- def _safe_next(self): |
- try: |
- return next(self._iterator) |
- except StopIteration: |
- return _last_iteration |
- |
- @internalcode |
- def loop(self, iterable): |
- if self._recurse is None: |
- raise TypeError('Tried to call non recursive loop. Maybe you ' |
- "forgot the 'recursive' modifier.") |
- return self._recurse(iterable, self._recurse, self.depth0 + 1) |
- |
- # a nifty trick to enhance the error message if someone tried to call |
- # the the loop without or with too many arguments. |
- __call__ = loop |
- del loop |
- |
- @property |
- def length(self): |
- if self._length is None: |
- # 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. |
- iterable = tuple(self._iterator) |
- self._iterator = iter(iterable) |
- self._length = len(iterable) + self.index0 + 1 |
- return self._length |
- |
- def __repr__(self): |
- return '<%s %r/%r>' % ( |
- self.__class__.__name__, |
- self.index, |
- self.length |
- ) |
- |
- |
-@implements_iterator |
-class LoopContextIterator(object): |
- """The iterator for a loop context.""" |
- __slots__ = ('context',) |
- |
- def __init__(self, context): |
- self.context = context |
- |
- def __iter__(self): |
- return self |
- |
- def __next__(self): |
- ctx = self.context |
- ctx.index0 += 1 |
- if ctx._after is _last_iteration: |
- raise StopIteration() |
- next_elem = ctx._after |
- ctx._after = ctx._safe_next() |
- return next_elem, ctx |
- |
- |
-class Macro(object): |
- """Wraps a macro function.""" |
- |
- def __init__(self, environment, func, name, arguments, defaults, |
- catch_kwargs, catch_varargs, caller): |
- self._environment = environment |
- self._func = func |
- self._argument_count = len(arguments) |
- self.name = name |
- self.arguments = arguments |
- self.defaults = defaults |
- self.catch_kwargs = catch_kwargs |
- self.catch_varargs = catch_varargs |
- self.caller = caller |
- |
- @internalcode |
- def __call__(self, *args, **kwargs): |
- # try to consume the positional arguments |
- arguments = list(args[:self._argument_count]) |
- off = len(arguments) |
- |
- # if the number of arguments consumed is not the number of |
- # arguments expected we start filling in keyword arguments |
- # and defaults. |
- if off != self._argument_count: |
- for idx, name in enumerate(self.arguments[len(arguments):]): |
- try: |
- value = kwargs.pop(name) |
- except KeyError: |
- try: |
- value = self.defaults[idx - self._argument_count + off] |
- except IndexError: |
- value = self._environment.undefined( |
- 'parameter %r was not provided' % name, name=name) |
- arguments.append(value) |
- |
- # it's important that the order of these arguments does not change |
- # if not also changed in the compiler's `function_scoping` method. |
- # the order is caller, keyword arguments, positional arguments! |
- if self.caller: |
- caller = kwargs.pop('caller', None) |
- if caller is None: |
- caller = self._environment.undefined('No caller defined', |
- name='caller') |
- arguments.append(caller) |
- if self.catch_kwargs: |
- arguments.append(kwargs) |
- elif kwargs: |
- raise TypeError('macro %r takes no keyword argument %r' % |
- (self.name, next(iter(kwargs)))) |
- if self.catch_varargs: |
- arguments.append(args[self._argument_count:]) |
- elif len(args) > self._argument_count: |
- raise TypeError('macro %r takes not more than %d argument(s)' % |
- (self.name, len(self.arguments))) |
- return self._func(*arguments) |
- |
- def __repr__(self): |
- return '<%s %s>' % ( |
- self.__class__.__name__, |
- self.name is None and 'anonymous' or repr(self.name) |
- ) |
- |
- |
-@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`: |
- |
- >>> foo = Undefined(name='foo') |
- >>> str(foo) |
- '' |
- >>> not foo |
- True |
- >>> foo + 42 |
- Traceback (most recent call last): |
- ... |
- UndefinedError: 'foo' is undefined |
- """ |
- __slots__ = ('_undefined_hint', '_undefined_obj', '_undefined_name', |
- '_undefined_exception') |
- |
- def __init__(self, hint=None, obj=missing, name=None, exc=UndefinedError): |
- self._undefined_hint = hint |
- self._undefined_obj = obj |
- self._undefined_name = name |
- self._undefined_exception = exc |
- |
- @internalcode |
- def _fail_with_undefined_error(self, *args, **kwargs): |
- """Regular callback function for undefined objects that raises an |
- `UndefinedError` on call. |
- """ |
- if self._undefined_hint is None: |
- if self._undefined_obj is missing: |
- hint = '%r is undefined' % self._undefined_name |
- elif not isinstance(self._undefined_name, string_types): |
- hint = '%s has no element %r' % ( |
- object_type_repr(self._undefined_obj), |
- self._undefined_name |
- ) |
- else: |
- hint = '%r has no attribute %r' % ( |
- object_type_repr(self._undefined_obj), |
- self._undefined_name |
- ) |
- else: |
- hint = self._undefined_hint |
- raise self._undefined_exception(hint) |
- |
- @internalcode |
- def __getattr__(self, name): |
- if name[:2] == '__': |
- raise AttributeError(name) |
- 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__ = \ |
- _fail_with_undefined_error |
- |
- def __eq__(self, other): |
- return type(self) is type(other) |
- |
- def __ne__(self, other): |
- return not self.__eq__(other) |
- |
- def __hash__(self): |
- return id(type(self)) |
- |
- def __str__(self): |
- return u'' |
- |
- def __len__(self): |
- return 0 |
- |
- def __iter__(self): |
- if 0: |
- yield None |
- |
- def __nonzero__(self): |
- return False |
- |
- def __repr__(self): |
- return 'Undefined' |
- |
- |
-@implements_to_string |
-class DebugUndefined(Undefined): |
- """An undefined that returns the debug info when printed. |
- |
- >>> foo = DebugUndefined(name='foo') |
- >>> str(foo) |
- '{{ foo }}' |
- >>> not foo |
- True |
- >>> foo + 42 |
- Traceback (most recent call last): |
- ... |
- UndefinedError: 'foo' is undefined |
- """ |
- __slots__ = () |
- |
- def __str__(self): |
- if self._undefined_hint is None: |
- if self._undefined_obj is missing: |
- return u'{{ %s }}' % self._undefined_name |
- return '{{ no such element: %s[%r] }}' % ( |
- object_type_repr(self._undefined_obj), |
- self._undefined_name |
- ) |
- return u'{{ undefined value printed: %s }}' % self._undefined_hint |
- |
- |
-@implements_to_string |
-class StrictUndefined(Undefined): |
- """An undefined that barks on print and iteration as well as boolean |
- tests and all kinds of comparisons. In other words: you can do nothing |
- with it except checking if it's defined using the `defined` test. |
- |
- >>> foo = StrictUndefined(name='foo') |
- >>> str(foo) |
- Traceback (most recent call last): |
- ... |
- UndefinedError: 'foo' is undefined |
- >>> not foo |
- Traceback (most recent call last): |
- ... |
- UndefinedError: 'foo' is undefined |
- >>> foo + 42 |
- Traceback (most recent call last): |
- ... |
- UndefinedError: 'foo' is undefined |
- """ |
- __slots__ = () |
- __iter__ = __str__ = __len__ = __nonzero__ = __eq__ = \ |
- __ne__ = __bool__ = __hash__ = \ |
- Undefined._fail_with_undefined_error |
- |
- |
-# remove remaining slots attributes, after the metaclass did the magic they |
-# are unneeded and irritating as they contain wrong data for the subclasses. |
-del Undefined.__slots__, DebugUndefined.__slots__, StrictUndefined.__slots__ |