1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# -*- coding: utf-8 -*- 2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)""" 3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) jinja2.runtime 4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ~~~~~~~~~~~~~~ 5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Runtime helpers. 7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) :copyright: (c) 2010 by the Jinja Team. 9b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) :license: BSD. 10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)""" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)from itertools import chain 12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)from jinja2.nodes import EvalContext, _context_function_types 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)from jinja2.utils import Markup, soft_unicode, escape, missing, concat, \ 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) internalcode, object_type_repr 15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \ 16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) TemplateNotFound 1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)from jinja2._compat import next, imap, text_type, iteritems, \ 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) implements_iterator, implements_to_string, string_types, PY2 19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# these variables are exported to the template runtime 22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)__all__ = ['LoopContext', 'TemplateReference', 'Macro', 'Markup', 23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'TemplateRuntimeError', 'missing', 'concat', 'escape', 24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'markup_join', 'unicode_join', 'to_string', 'identity', 25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'TemplateNotFound'] 26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#: the name of the function that is used to convert something into 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#: a string. We can just use the text type here. 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)to_string = text_type 30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#: the identity function. Useful for certain things in the environment 32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)identity = lambda x: x 33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)_last_iteration = object() 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def markup_join(seq): 38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Concatenation that escapes if necessary and converts to unicode.""" 39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) buf = [] 40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) iterator = imap(soft_unicode, seq) 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for arg in iterator: 42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) buf.append(arg) 43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if hasattr(arg, '__html__'): 44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return Markup(u'').join(chain(buf, iterator)) 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return concat(buf) 46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def unicode_join(seq): 49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Simple args to unicode conversion and concatenation.""" 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return concat(imap(text_type, seq)) 51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)def new_context(environment, template_name, blocks, vars=None, 54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) shared=None, globals=None, locals=None): 55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Internal helper to for context creation.""" 56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if vars is None: 57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) vars = {} 58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if shared: 59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) parent = vars 60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) else: 61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) parent = dict(globals or (), **vars) 62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if locals: 63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # if the parent is shared a copy should be created because 64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # we don't want to modify the dict passed 65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if shared: 66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) parent = dict(parent) 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for key, value in iteritems(locals): 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if key[:2] == 'l_' and value is not missing: 69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) parent[key[2:]] = value 70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return Context(environment, parent, template_name, blocks) 71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class TemplateReference(object): 74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """The `self` in templates.""" 75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __init__(self, context): 77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.__context = context 78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __getitem__(self, name): 80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) blocks = self.__context.blocks[name] 81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return BlockReference(name, self.__context, blocks, 0) 82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __repr__(self): 84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return '<%s %r>' % ( 85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.__class__.__name__, 86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.__context.name 87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ) 88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Context(object): 91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """The template context holds the variables of a template. It stores the 92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) values passed to the template and also the names the template exports. 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Creating instances is neither supported nor useful as it's created 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) automatically at various stages of the template evaluation and should not 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) be created by hand. 96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) The context is immutable. Modifications on :attr:`parent` **must not** 98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) happen and modifications on :attr:`vars` are allowed from generated 99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) template code only. Template filters and global functions marked as 100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) :func:`contextfunction`\s get the active context passed as first argument 101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) and are allowed to access the context read-only. 102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) The template context supports read only dict operations (`get`, 104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) `keys`, `values`, `items`, `iterkeys`, `itervalues`, `iteritems`, 105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) `__getitem__`, `__contains__`). Additionally there is a :meth:`resolve` 106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) method that doesn't fail with a `KeyError` but returns an 107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) :class:`Undefined` object for missing variables. 108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __slots__ = ('parent', 'vars', 'environment', 'eval_ctx', 'exported_vars', 110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'name', 'blocks', '__weakref__') 111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __init__(self, environment, parent, name, blocks): 113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.parent = parent 114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.vars = {} 115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.environment = environment 116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.eval_ctx = EvalContext(self.environment, name) 117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.exported_vars = set() 118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.name = name 119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # create the initial mapping of blocks. Whenever template inheritance 121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # takes place the runtime will update this mapping with the new blocks 122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # from the template. 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self.blocks = dict((k, [v]) for k, v in iteritems(blocks)) 124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def super(self, name, current): 126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Render a parent block.""" 127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) try: 128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) blocks = self.blocks[name] 129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) index = blocks.index(current) + 1 130b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) blocks[index] 131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) except LookupError: 132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self.environment.undefined('there is no parent block ' 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'called %r.' % name, 134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) name='super') 135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return BlockReference(name, self, blocks, index) 136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def get(self, key, default=None): 138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Returns an item from the template context, if it doesn't exist 139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) `default` is returned. 140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) try: 142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self[key] 143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) except KeyError: 144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return default 145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def resolve(self, key): 147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Looks up a variable like `__getitem__` or `get` but returns an 148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) :class:`Undefined` object with the name of the name looked up. 149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if key in self.vars: 151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self.vars[key] 152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if key in self.parent: 153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self.parent[key] 154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self.environment.undefined(name=key) 155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def get_exported(self): 157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Get a new dict with the exported variables.""" 158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return dict((k, self.vars[k]) for k in self.exported_vars) 159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def get_all(self): 161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Return a copy of the complete context as dict including the 162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) exported variables. 163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return dict(self.parent, **self.vars) 165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @internalcode 167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def call(__self, __obj, *args, **kwargs): 168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Call the callable with the arguments and keyword arguments 169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) provided but inject the active context or environment as first 170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) argument if the callable is a :func:`contextfunction` or 171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) :func:`environmentfunction`. 172b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if __debug__: 174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __traceback_hide__ = True 17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) # Allow callable classes to take a context 17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fn = __obj.__call__ 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for fn_type in ('contextfunction', 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'evalcontextfunction', 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 'environmentfunction'): 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if hasattr(fn, fn_type): 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) __obj = fn 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) break 18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if isinstance(__obj, _context_function_types): 186b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if getattr(__obj, 'contextfunction', 0): 187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) args = (__self,) + args 188b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) elif getattr(__obj, 'evalcontextfunction', 0): 189b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) args = (__self.eval_ctx,) + args 190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) elif getattr(__obj, 'environmentfunction', 0): 191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) args = (__self.environment,) + args 192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) try: 193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return __obj(*args, **kwargs) 194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) except StopIteration: 195b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return __self.environment.undefined('value was undefined because ' 196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'a callable raised a ' 197b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'StopIteration exception') 198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def derived(self, locals=None): 200b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Internal helper function to create a derived context.""" 201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) context = new_context(self.environment, self.name, {}, 202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.parent, True, None, locals) 203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) context.vars.update(self.vars) 204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) context.eval_ctx = self.eval_ctx 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) context.blocks.update((k, list(v)) for k, v in iteritems(self.blocks)) 206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return context 207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def _all(meth): 209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) proxy = lambda self: getattr(self.get_all(), meth)() 210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) proxy.__doc__ = getattr(dict, meth).__doc__ 211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) proxy.__name__ = meth 212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return proxy 213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) keys = _all('keys') 215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) values = _all('values') 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) items = _all('items') 217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # not available on python 3 21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if PY2: 220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) iterkeys = _all('iterkeys') 221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) itervalues = _all('itervalues') 222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) iteritems = _all('iteritems') 223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) del _all 224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __contains__(self, name): 226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return name in self.vars or name in self.parent 227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 228b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __getitem__(self, key): 229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Lookup a variable or raise `KeyError` if the variable is 230b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) undefined. 231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) item = self.resolve(key) 233b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if isinstance(item, Undefined): 234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) raise KeyError(key) 235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return item 236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 237b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __repr__(self): 238b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return '<%s %s of %r>' % ( 239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.__class__.__name__, 240b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) repr(self.get_all()), 241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.name 242b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ) 243b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 245b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# register the context as mapping if possible 246b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)try: 247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) from collections import Mapping 248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Mapping.register(Context) 249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)except ImportError: 250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) pass 251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 252b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class BlockReference(object): 254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """One block on a template reference.""" 255b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 256b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __init__(self, name, context, stack, depth): 257b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.name = name 258b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._context = context 259b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._stack = stack 260b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._depth = depth 261b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 262b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @property 263b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def super(self): 264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Super the block.""" 265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._depth + 1 >= len(self._stack): 266b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self._context.environment. \ 267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) undefined('there is no parent block called %r.' % 268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.name, name='super') 269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return BlockReference(self.name, self._context, self._stack, 270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._depth + 1) 271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @internalcode 273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __call__(self): 274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) rv = concat(self._stack[self._depth](self._context)) 275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._context.eval_ctx.autoescape: 276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) rv = Markup(rv) 277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return rv 278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 280b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class LoopContext(object): 281b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """A loop context for dynamic iteration.""" 282b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __init__(self, iterable, recurse=None, depth0=0): 284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._iterator = iter(iterable) 285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._recurse = recurse 28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._after = self._safe_next() 287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.index0 = -1 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self.depth0 = depth0 289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # try to get the length of the iterable early. This must be done 291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # here because there are some broken iterators around where there 292b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # __len__ is the number of iterations left (i'm looking at your 293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # listreverseiterator!). 294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) try: 295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._length = len(iterable) 296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) except (TypeError, AttributeError): 297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._length = None 298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def cycle(self, *args): 300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Cycles among the arguments with the current loop index.""" 301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if not args: 302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) raise TypeError('no items for cycling given') 303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return args[self.index0 % len(args)] 304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) first = property(lambda x: x.index0 == 0) 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) last = property(lambda x: x._after is _last_iteration) 307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) index = property(lambda x: x.index0 + 1) 308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) revindex = property(lambda x: x.length - x.index0) 309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) revindex0 = property(lambda x: x.length - x.index) 31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) depth = property(lambda x: x.depth0 + 1) 311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __len__(self): 313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self.length 314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __iter__(self): 316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return LoopContextIterator(self) 317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def _safe_next(self): 31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) try: 32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return next(self._iterator) 32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) except StopIteration: 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return _last_iteration 32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @internalcode 325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def loop(self, iterable): 326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._recurse is None: 327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) raise TypeError('Tried to call non recursive loop. Maybe you ' 328b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "forgot the 'recursive' modifier.") 32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return self._recurse(iterable, self._recurse, self.depth0 + 1) 330b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # a nifty trick to enhance the error message if someone tried to call 332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # the the loop without or with too many arguments. 333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __call__ = loop 334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) del loop 335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @property 337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def length(self): 338b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._length is None: 339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # if was not possible to get the length of the iterator when 340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # the loop context was created (ie: iterating over a generator) 341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # we have to convert the iterable into a sequence and use the 342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # length of that. 343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) iterable = tuple(self._iterator) 344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._iterator = iter(iterable) 345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._length = len(iterable) + self.index0 + 1 346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self._length 347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __repr__(self): 349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return '<%s %r/%r>' % ( 350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.__class__.__name__, 351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.index, 352b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.length 353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ) 354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)@implements_iterator 357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class LoopContextIterator(object): 358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """The iterator for a loop context.""" 359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __slots__ = ('context',) 360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __init__(self, context): 362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.context = context 363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __iter__(self): 365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self 366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __next__(self): 368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ctx = self.context 369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ctx.index0 += 1 37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if ctx._after is _last_iteration: 37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) raise StopIteration() 37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) next_elem = ctx._after 37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ctx._after = ctx._safe_next() 37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return next_elem, ctx 375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 377b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Macro(object): 378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Wraps a macro function.""" 379b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 380b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __init__(self, environment, func, name, arguments, defaults, 381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) catch_kwargs, catch_varargs, caller): 382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._environment = environment 383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._func = func 384b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._argument_count = len(arguments) 385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.name = name 386b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.arguments = arguments 387b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.defaults = defaults 388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.catch_kwargs = catch_kwargs 389b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.catch_varargs = catch_varargs 390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.caller = caller 391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 392b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @internalcode 393b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __call__(self, *args, **kwargs): 394b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # try to consume the positional arguments 395b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) arguments = list(args[:self._argument_count]) 396b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) off = len(arguments) 397b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 398b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # if the number of arguments consumed is not the number of 399b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # arguments expected we start filling in keyword arguments 400b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # and defaults. 401b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if off != self._argument_count: 402b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for idx, name in enumerate(self.arguments[len(arguments):]): 403b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) try: 404b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) value = kwargs.pop(name) 405b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) except KeyError: 406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) try: 407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) value = self.defaults[idx - self._argument_count + off] 408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) except IndexError: 409b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) value = self._environment.undefined( 410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 'parameter %r was not provided' % name, name=name) 411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) arguments.append(value) 412b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 413b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # it's important that the order of these arguments does not change 414b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # if not also changed in the compiler's `function_scoping` method. 415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) # the order is caller, keyword arguments, positional arguments! 416b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self.caller: 417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) caller = kwargs.pop('caller', None) 418b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if caller is None: 419b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) caller = self._environment.undefined('No caller defined', 420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) name='caller') 421b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) arguments.append(caller) 422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self.catch_kwargs: 423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) arguments.append(kwargs) 424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) elif kwargs: 425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) raise TypeError('macro %r takes no keyword argument %r' % 426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) (self.name, next(iter(kwargs)))) 427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self.catch_varargs: 428b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) arguments.append(args[self._argument_count:]) 429b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) elif len(args) > self._argument_count: 430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) raise TypeError('macro %r takes not more than %d argument(s)' % 431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) (self.name, len(self.arguments))) 432b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self._func(*arguments) 433b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 434b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __repr__(self): 435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return '<%s %s>' % ( 436b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.__class__.__name__, 437b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self.name is None and 'anonymous' or repr(self.name) 438b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ) 439b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 440b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)@implements_to_string 442b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Undefined(object): 443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """The default undefined type. This undefined type can be printed and 444b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) iterated over, but every other access will raise an :exc:`UndefinedError`: 445b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 446b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> foo = Undefined(name='foo') 447b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> str(foo) 448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) '' 449b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> not foo 450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) True 451b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> foo + 42 452b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Traceback (most recent call last): 453b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ... 454b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UndefinedError: 'foo' is undefined 455b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 456b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __slots__ = ('_undefined_hint', '_undefined_obj', '_undefined_name', 457b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) '_undefined_exception') 458b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 459b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __init__(self, hint=None, obj=missing, name=None, exc=UndefinedError): 460b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._undefined_hint = hint 461b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._undefined_obj = obj 462b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._undefined_name = name 463b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._undefined_exception = exc 464b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 465b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @internalcode 466b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def _fail_with_undefined_error(self, *args, **kwargs): 467b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """Regular callback function for undefined objects that raises an 468b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) `UndefinedError` on call. 469b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 470b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._undefined_hint is None: 471b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._undefined_obj is missing: 472b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) hint = '%r is undefined' % self._undefined_name 47358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) elif not isinstance(self._undefined_name, string_types): 474b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) hint = '%s has no element %r' % ( 475b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) object_type_repr(self._undefined_obj), 476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._undefined_name 477b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ) 478b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) else: 479b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) hint = '%r has no attribute %r' % ( 480b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) object_type_repr(self._undefined_obj), 481b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._undefined_name 482b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ) 483b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) else: 484b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) hint = self._undefined_hint 485b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) raise self._undefined_exception(hint) 486b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 487b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) @internalcode 488b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __getattr__(self, name): 489b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if name[:2] == '__': 490b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) raise AttributeError(name) 491b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return self._fail_with_undefined_error() 492b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 493b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __add__ = __radd__ = __mul__ = __rmul__ = __div__ = __rdiv__ = \ 494b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __truediv__ = __rtruediv__ = __floordiv__ = __rfloordiv__ = \ 495b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __mod__ = __rmod__ = __pos__ = __neg__ = __call__ = \ 496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __getitem__ = __lt__ = __le__ = __gt__ = __ge__ = __int__ = \ 497b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __float__ = __complex__ = __pow__ = __rpow__ = \ 498b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) _fail_with_undefined_error 499b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 50058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __eq__(self, other): 50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return type(self) is type(other) 50258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 50358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __ne__(self, other): 50458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return not self.__eq__(other) 50558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 50658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __hash__(self): 50758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return id(type(self)) 508b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 50958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __str__(self): 510b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return u'' 511b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 512b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __len__(self): 513b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return 0 514b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 515b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __iter__(self): 516b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if 0: 517b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) yield None 518b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 519b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __nonzero__(self): 520b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return False 521b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 522b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) def __repr__(self): 523b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return 'Undefined' 524b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 525b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)@implements_to_string 527b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class DebugUndefined(Undefined): 528b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """An undefined that returns the debug info when printed. 529b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 530b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> foo = DebugUndefined(name='foo') 531b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> str(foo) 532b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) '{{ foo }}' 533b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> not foo 534b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) True 535b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> foo + 42 536b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Traceback (most recent call last): 537b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ... 538b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UndefinedError: 'foo' is undefined 539b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 540b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __slots__ = () 541b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 54258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __str__(self): 543b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._undefined_hint is None: 544b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if self._undefined_obj is missing: 545b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return u'{{ %s }}' % self._undefined_name 546b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return '{{ no such element: %s[%r] }}' % ( 547b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) object_type_repr(self._undefined_obj), 548b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) self._undefined_name 549b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ) 550b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return u'{{ undefined value printed: %s }}' % self._undefined_hint 551b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 552b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 55358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)@implements_to_string 554b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class StrictUndefined(Undefined): 555b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """An undefined that barks on print and iteration as well as boolean 556b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) tests and all kinds of comparisons. In other words: you can do nothing 557b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) with it except checking if it's defined using the `defined` test. 558b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 559b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> foo = StrictUndefined(name='foo') 560b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> str(foo) 561b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Traceback (most recent call last): 562b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ... 563b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UndefinedError: 'foo' is undefined 564b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> not foo 565b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Traceback (most recent call last): 566b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ... 567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UndefinedError: 'foo' is undefined 568b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) >>> foo + 42 569b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Traceback (most recent call last): 570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ... 571b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UndefinedError: 'foo' is undefined 572b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) """ 573b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) __slots__ = () 57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) __iter__ = __str__ = __len__ = __nonzero__ = __eq__ = \ 57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) __ne__ = __bool__ = __hash__ = \ 57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Undefined._fail_with_undefined_error 577b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 579b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# remove remaining slots attributes, after the metaclass did the magic they 580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)# are unneeded and irritating as they contain wrong data for the subclasses. 581b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)del Undefined.__slots__, DebugUndefined.__slots__, StrictUndefined.__slots__ 582