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