123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918 |
- # mako/runtime.py
- # Copyright (C) 2006-2016 the Mako authors and contributors <see AUTHORS file>
- #
- # This module is part of Mako and is released under
- # the MIT License: http://www.opensource.org/licenses/mit-license.php
- """provides runtime services for templates, including Context,
- Namespace, and various helper functions."""
- from mako import exceptions, util, compat
- from mako.compat import compat_builtins
- import sys
- class Context(object):
- """Provides runtime namespace, output buffer, and various
- callstacks for templates.
- See :ref:`runtime_toplevel` for detail on the usage of
- :class:`.Context`.
- """
- def __init__(self, buffer, **data):
- self._buffer_stack = [buffer]
- self._data = data
- self._kwargs = data.copy()
- self._with_template = None
- self._outputting_as_unicode = None
- self.namespaces = {}
- # "capture" function which proxies to the
- # generic "capture" function
- self._data['capture'] = compat.partial(capture, self)
- # "caller" stack used by def calls with content
- self.caller_stack = self._data['caller'] = CallerStack()
- def _set_with_template(self, t):
- self._with_template = t
- illegal_names = t.reserved_names.intersection(self._data)
- if illegal_names:
- raise exceptions.NameConflictError(
- "Reserved words passed to render(): %s" %
- ", ".join(illegal_names))
- @property
- def lookup(self):
- """Return the :class:`.TemplateLookup` associated
- with this :class:`.Context`.
- """
- return self._with_template.lookup
- @property
- def kwargs(self):
- """Return the dictionary of top level keyword arguments associated
- with this :class:`.Context`.
- This dictionary only includes the top-level arguments passed to
- :meth:`.Template.render`. It does not include names produced within
- the template execution such as local variable names or special names
- such as ``self``, ``next``, etc.
- The purpose of this dictionary is primarily for the case that
- a :class:`.Template` accepts arguments via its ``<%page>`` tag,
- which are normally expected to be passed via :meth:`.Template.render`,
- except the template is being called in an inheritance context,
- using the ``body()`` method. :attr:`.Context.kwargs` can then be
- used to propagate these arguments to the inheriting template::
- ${next.body(**context.kwargs)}
- """
- return self._kwargs.copy()
- def push_caller(self, caller):
- """Push a ``caller`` callable onto the callstack for
- this :class:`.Context`."""
- self.caller_stack.append(caller)
- def pop_caller(self):
- """Pop a ``caller`` callable onto the callstack for this
- :class:`.Context`."""
- del self.caller_stack[-1]
- def keys(self):
- """Return a list of all names established in this :class:`.Context`."""
- return list(self._data.keys())
- def __getitem__(self, key):
- if key in self._data:
- return self._data[key]
- else:
- return compat_builtins.__dict__[key]
- def _push_writer(self):
- """push a capturing buffer onto this Context and return
- the new writer function."""
- buf = util.FastEncodingBuffer()
- self._buffer_stack.append(buf)
- return buf.write
- def _pop_buffer_and_writer(self):
- """pop the most recent capturing buffer from this Context
- and return the current writer after the pop.
- """
- buf = self._buffer_stack.pop()
- return buf, self._buffer_stack[-1].write
- def _push_buffer(self):
- """push a capturing buffer onto this Context."""
- self._push_writer()
- def _pop_buffer(self):
- """pop the most recent capturing buffer from this Context."""
- return self._buffer_stack.pop()
- def get(self, key, default=None):
- """Return a value from this :class:`.Context`."""
- return self._data.get(key, compat_builtins.__dict__.get(key, default))
- def write(self, string):
- """Write a string to this :class:`.Context` object's
- underlying output buffer."""
- self._buffer_stack[-1].write(string)
- def writer(self):
- """Return the current writer function."""
- return self._buffer_stack[-1].write
- def _copy(self):
- c = Context.__new__(Context)
- c._buffer_stack = self._buffer_stack
- c._data = self._data.copy()
- c._kwargs = self._kwargs
- c._with_template = self._with_template
- c._outputting_as_unicode = self._outputting_as_unicode
- c.namespaces = self.namespaces
- c.caller_stack = self.caller_stack
- return c
- def _locals(self, d):
- """Create a new :class:`.Context` with a copy of this
- :class:`.Context`'s current state,
- updated with the given dictionary.
- The :attr:`.Context.kwargs` collection remains
- unaffected.
- """
- if not d:
- return self
- c = self._copy()
- c._data.update(d)
- return c
- def _clean_inheritance_tokens(self):
- """create a new copy of this :class:`.Context`. with
- tokens related to inheritance state removed."""
- c = self._copy()
- x = c._data
- x.pop('self', None)
- x.pop('parent', None)
- x.pop('next', None)
- return c
- class CallerStack(list):
- def __init__(self):
- self.nextcaller = None
- def __nonzero__(self):
- return self.__bool__()
- def __bool__(self):
- return len(self) and self._get_caller() and True or False
- def _get_caller(self):
- # this method can be removed once
- # codegen MAGIC_NUMBER moves past 7
- return self[-1]
- def __getattr__(self, key):
- return getattr(self._get_caller(), key)
- def _push_frame(self):
- frame = self.nextcaller or None
- self.append(frame)
- self.nextcaller = None
- return frame
- def _pop_frame(self):
- self.nextcaller = self.pop()
- class Undefined(object):
- """Represents an undefined value in a template.
- All template modules have a constant value
- ``UNDEFINED`` present which is an instance of this
- object.
- """
- def __str__(self):
- raise NameError("Undefined")
- def __nonzero__(self):
- return self.__bool__()
- def __bool__(self):
- return False
- UNDEFINED = Undefined()
- STOP_RENDERING = ""
- class LoopStack(object):
- """a stack for LoopContexts that implements the context manager protocol
- to automatically pop off the top of the stack on context exit
- """
- def __init__(self):
- self.stack = []
- def _enter(self, iterable):
- self._push(iterable)
- return self._top
- def _exit(self):
- self._pop()
- return self._top
- @property
- def _top(self):
- if self.stack:
- return self.stack[-1]
- else:
- return self
- def _pop(self):
- return self.stack.pop()
- def _push(self, iterable):
- new = LoopContext(iterable)
- if self.stack:
- new.parent = self.stack[-1]
- return self.stack.append(new)
- def __getattr__(self, key):
- raise exceptions.RuntimeException("No loop context is established")
- def __iter__(self):
- return iter(self._top)
- class LoopContext(object):
- """A magic loop variable.
- Automatically accessible in any ``% for`` block.
- See the section :ref:`loop_context` for usage
- notes.
- :attr:`parent` -> :class:`.LoopContext` or ``None``
- The parent loop, if one exists.
- :attr:`index` -> `int`
- The 0-based iteration count.
- :attr:`reverse_index` -> `int`
- The number of iterations remaining.
- :attr:`first` -> `bool`
- ``True`` on the first iteration, ``False`` otherwise.
- :attr:`last` -> `bool`
- ``True`` on the last iteration, ``False`` otherwise.
- :attr:`even` -> `bool`
- ``True`` when ``index`` is even.
- :attr:`odd` -> `bool`
- ``True`` when ``index`` is odd.
- """
- def __init__(self, iterable):
- self._iterable = iterable
- self.index = 0
- self.parent = None
- def __iter__(self):
- for i in self._iterable:
- yield i
- self.index += 1
- @util.memoized_instancemethod
- def __len__(self):
- return len(self._iterable)
- @property
- def reverse_index(self):
- return len(self) - self.index - 1
- @property
- def first(self):
- return self.index == 0
- @property
- def last(self):
- return self.index == len(self) - 1
- @property
- def even(self):
- return not self.odd
- @property
- def odd(self):
- return bool(self.index % 2)
- def cycle(self, *values):
- """Cycle through values as the loop progresses.
- """
- if not values:
- raise ValueError("You must provide values to cycle through")
- return values[self.index % len(values)]
- class _NSAttr(object):
- def __init__(self, parent):
- self.__parent = parent
- def __getattr__(self, key):
- ns = self.__parent
- while ns:
- if hasattr(ns.module, key):
- return getattr(ns.module, key)
- else:
- ns = ns.inherits
- raise AttributeError(key)
- class Namespace(object):
- """Provides access to collections of rendering methods, which
- can be local, from other templates, or from imported modules.
- To access a particular rendering method referenced by a
- :class:`.Namespace`, use plain attribute access:
- .. sourcecode:: mako
- ${some_namespace.foo(x, y, z)}
- :class:`.Namespace` also contains several built-in attributes
- described here.
- """
- def __init__(self, name, context,
- callables=None, inherits=None,
- populate_self=True, calling_uri=None):
- self.name = name
- self.context = context
- self.inherits = inherits
- if callables is not None:
- self.callables = dict([(c.__name__, c) for c in callables])
- callables = ()
- module = None
- """The Python module referenced by this :class:`.Namespace`.
- If the namespace references a :class:`.Template`, then
- this module is the equivalent of ``template.module``,
- i.e. the generated module for the template.
- """
- template = None
- """The :class:`.Template` object referenced by this
- :class:`.Namespace`, if any.
- """
- context = None
- """The :class:`.Context` object for this :class:`.Namespace`.
- Namespaces are often created with copies of contexts that
- contain slightly different data, particularly in inheritance
- scenarios. Using the :class:`.Context` off of a :class:`.Namespace` one
- can traverse an entire chain of templates that inherit from
- one-another.
- """
- filename = None
- """The path of the filesystem file used for this
- :class:`.Namespace`'s module or template.
- If this is a pure module-based
- :class:`.Namespace`, this evaluates to ``module.__file__``. If a
- template-based namespace, it evaluates to the original
- template file location.
- """
- uri = None
- """The URI for this :class:`.Namespace`'s template.
- I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`.
- This is the equivalent of :attr:`.Template.uri`.
- """
- _templateuri = None
- @util.memoized_property
- def attr(self):
- """Access module level attributes by name.
- This accessor allows templates to supply "scalar"
- attributes which are particularly handy in inheritance
- relationships.
- .. seealso::
- :ref:`inheritance_attr`
- :ref:`namespace_attr_for_includes`
- """
- return _NSAttr(self)
- def get_namespace(self, uri):
- """Return a :class:`.Namespace` corresponding to the given ``uri``.
- If the given ``uri`` is a relative URI (i.e. it does not
- contain a leading slash ``/``), the ``uri`` is adjusted to
- be relative to the ``uri`` of the namespace itself. This
- method is therefore mostly useful off of the built-in
- ``local`` namespace, described in :ref:`namespace_local`.
- In
- most cases, a template wouldn't need this function, and
- should instead use the ``<%namespace>`` tag to load
- namespaces. However, since all ``<%namespace>`` tags are
- evaluated before the body of a template ever runs,
- this method can be used to locate namespaces using
- expressions that were generated within the body code of
- the template, or to conditionally use a particular
- namespace.
- """
- key = (self, uri)
- if key in self.context.namespaces:
- return self.context.namespaces[key]
- else:
- ns = TemplateNamespace(uri, self.context._copy(),
- templateuri=uri,
- calling_uri=self._templateuri)
- self.context.namespaces[key] = ns
- return ns
- def get_template(self, uri):
- """Return a :class:`.Template` from the given ``uri``.
- The ``uri`` resolution is relative to the ``uri`` of this
- :class:`.Namespace` object's :class:`.Template`.
- """
- return _lookup_template(self.context, uri, self._templateuri)
- def get_cached(self, key, **kwargs):
- """Return a value from the :class:`.Cache` referenced by this
- :class:`.Namespace` object's :class:`.Template`.
- The advantage to this method versus direct access to the
- :class:`.Cache` is that the configuration parameters
- declared in ``<%page>`` take effect here, thereby calling
- up the same configured backend as that configured
- by ``<%page>``.
- """
- return self.cache.get(key, **kwargs)
- @property
- def cache(self):
- """Return the :class:`.Cache` object referenced
- by this :class:`.Namespace` object's
- :class:`.Template`.
- """
- return self.template.cache
- def include_file(self, uri, **kwargs):
- """Include a file at the given ``uri``."""
- _include_file(self.context, uri, self._templateuri, **kwargs)
- def _populate(self, d, l):
- for ident in l:
- if ident == '*':
- for (k, v) in self._get_star():
- d[k] = v
- else:
- d[ident] = getattr(self, ident)
- def _get_star(self):
- if self.callables:
- for key in self.callables:
- yield (key, self.callables[key])
- def __getattr__(self, key):
- if key in self.callables:
- val = self.callables[key]
- elif self.inherits:
- val = getattr(self.inherits, key)
- else:
- raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
- setattr(self, key, val)
- return val
- class TemplateNamespace(Namespace):
- """A :class:`.Namespace` specific to a :class:`.Template` instance."""
- def __init__(self, name, context, template=None, templateuri=None,
- callables=None, inherits=None,
- populate_self=True, calling_uri=None):
- self.name = name
- self.context = context
- self.inherits = inherits
- if callables is not None:
- self.callables = dict([(c.__name__, c) for c in callables])
- if templateuri is not None:
- self.template = _lookup_template(context, templateuri,
- calling_uri)
- self._templateuri = self.template.module._template_uri
- elif template is not None:
- self.template = template
- self._templateuri = template.module._template_uri
- else:
- raise TypeError("'template' argument is required.")
- if populate_self:
- lclcallable, lclcontext = \
- _populate_self_namespace(context, self.template,
- self_ns=self)
- @property
- def module(self):
- """The Python module referenced by this :class:`.Namespace`.
- If the namespace references a :class:`.Template`, then
- this module is the equivalent of ``template.module``,
- i.e. the generated module for the template.
- """
- return self.template.module
- @property
- def filename(self):
- """The path of the filesystem file used for this
- :class:`.Namespace`'s module or template.
- """
- return self.template.filename
- @property
- def uri(self):
- """The URI for this :class:`.Namespace`'s template.
- I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`.
- This is the equivalent of :attr:`.Template.uri`.
- """
- return self.template.uri
- def _get_star(self):
- if self.callables:
- for key in self.callables:
- yield (key, self.callables[key])
- def get(key):
- callable_ = self.template._get_def_callable(key)
- return compat.partial(callable_, self.context)
- for k in self.template.module._exports:
- yield (k, get(k))
- def __getattr__(self, key):
- if key in self.callables:
- val = self.callables[key]
- elif self.template.has_def(key):
- callable_ = self.template._get_def_callable(key)
- val = compat.partial(callable_, self.context)
- elif self.inherits:
- val = getattr(self.inherits, key)
- else:
- raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
- setattr(self, key, val)
- return val
- class ModuleNamespace(Namespace):
- """A :class:`.Namespace` specific to a Python module instance."""
- def __init__(self, name, context, module,
- callables=None, inherits=None,
- populate_self=True, calling_uri=None):
- self.name = name
- self.context = context
- self.inherits = inherits
- if callables is not None:
- self.callables = dict([(c.__name__, c) for c in callables])
- mod = __import__(module)
- for token in module.split('.')[1:]:
- mod = getattr(mod, token)
- self.module = mod
- @property
- def filename(self):
- """The path of the filesystem file used for this
- :class:`.Namespace`'s module or template.
- """
- return self.module.__file__
- def _get_star(self):
- if self.callables:
- for key in self.callables:
- yield (key, self.callables[key])
- for key in dir(self.module):
- if key[0] != '_':
- callable_ = getattr(self.module, key)
- if compat.callable(callable_):
- yield key, compat.partial(callable_, self.context)
- def __getattr__(self, key):
- if key in self.callables:
- val = self.callables[key]
- elif hasattr(self.module, key):
- callable_ = getattr(self.module, key)
- val = compat.partial(callable_, self.context)
- elif self.inherits:
- val = getattr(self.inherits, key)
- else:
- raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
- setattr(self, key, val)
- return val
- def supports_caller(func):
- """Apply a caller_stack compatibility decorator to a plain
- Python function.
- See the example in :ref:`namespaces_python_modules`.
- """
- def wrap_stackframe(context, *args, **kwargs):
- context.caller_stack._push_frame()
- try:
- return func(context, *args, **kwargs)
- finally:
- context.caller_stack._pop_frame()
- return wrap_stackframe
- def capture(context, callable_, *args, **kwargs):
- """Execute the given template def, capturing the output into
- a buffer.
- See the example in :ref:`namespaces_python_modules`.
- """
- if not compat.callable(callable_):
- raise exceptions.RuntimeException(
- "capture() function expects a callable as "
- "its argument (i.e. capture(func, *args, **kwargs))"
- )
- context._push_buffer()
- try:
- callable_(*args, **kwargs)
- finally:
- buf = context._pop_buffer()
- return buf.getvalue()
- def _decorate_toplevel(fn):
- def decorate_render(render_fn):
- def go(context, *args, **kw):
- def y(*args, **kw):
- return render_fn(context, *args, **kw)
- try:
- y.__name__ = render_fn.__name__[7:]
- except TypeError:
- # < Python 2.4
- pass
- return fn(y)(context, *args, **kw)
- return go
- return decorate_render
- def _decorate_inline(context, fn):
- def decorate_render(render_fn):
- dec = fn(render_fn)
- def go(*args, **kw):
- return dec(context, *args, **kw)
- return go
- return decorate_render
- def _include_file(context, uri, calling_uri, **kwargs):
- """locate the template from the given uri and include it in
- the current output."""
- template = _lookup_template(context, uri, calling_uri)
- (callable_, ctx) = _populate_self_namespace(
- context._clean_inheritance_tokens(),
- template)
- kwargs = _kwargs_for_include(callable_, context._data, **kwargs)
- if template.include_error_handler:
- try:
- callable_(ctx, **kwargs)
- except Exception:
- result = template.include_error_handler(ctx, compat.exception_as())
- if not result:
- compat.reraise(*sys.exc_info())
- else:
- callable_(ctx, **kwargs)
- def _inherit_from(context, uri, calling_uri):
- """called by the _inherit method in template modules to set
- up the inheritance chain at the start of a template's
- execution."""
- if uri is None:
- return None
- template = _lookup_template(context, uri, calling_uri)
- self_ns = context['self']
- ih = self_ns
- while ih.inherits is not None:
- ih = ih.inherits
- lclcontext = context._locals({'next': ih})
- ih.inherits = TemplateNamespace("self:%s" % template.uri,
- lclcontext,
- template=template,
- populate_self=False)
- context._data['parent'] = lclcontext._data['local'] = ih.inherits
- callable_ = getattr(template.module, '_mako_inherit', None)
- if callable_ is not None:
- ret = callable_(template, lclcontext)
- if ret:
- return ret
- gen_ns = getattr(template.module, '_mako_generate_namespaces', None)
- if gen_ns is not None:
- gen_ns(context)
- return (template.callable_, lclcontext)
- def _lookup_template(context, uri, relativeto):
- lookup = context._with_template.lookup
- if lookup is None:
- raise exceptions.TemplateLookupException(
- "Template '%s' has no TemplateLookup associated" %
- context._with_template.uri)
- uri = lookup.adjust_uri(uri, relativeto)
- try:
- return lookup.get_template(uri)
- except exceptions.TopLevelLookupException:
- raise exceptions.TemplateLookupException(str(compat.exception_as()))
- def _populate_self_namespace(context, template, self_ns=None):
- if self_ns is None:
- self_ns = TemplateNamespace('self:%s' % template.uri,
- context, template=template,
- populate_self=False)
- context._data['self'] = context._data['local'] = self_ns
- if hasattr(template.module, '_mako_inherit'):
- ret = template.module._mako_inherit(template, context)
- if ret:
- return ret
- return (template.callable_, context)
- def _render(template, callable_, args, data, as_unicode=False):
- """create a Context and return the string
- output of the given template and template callable."""
- if as_unicode:
- buf = util.FastEncodingBuffer(as_unicode=True)
- elif template.bytestring_passthrough:
- buf = compat.StringIO()
- else:
- buf = util.FastEncodingBuffer(
- as_unicode=as_unicode,
- encoding=template.output_encoding,
- errors=template.encoding_errors)
- context = Context(buf, **data)
- context._outputting_as_unicode = as_unicode
- context._set_with_template(template)
- _render_context(template, callable_, context, *args,
- **_kwargs_for_callable(callable_, data))
- return context._pop_buffer().getvalue()
- def _kwargs_for_callable(callable_, data):
- argspec = compat.inspect_func_args(callable_)
- # for normal pages, **pageargs is usually present
- if argspec[2]:
- return data
- # for rendering defs from the top level, figure out the args
- namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
- kwargs = {}
- for arg in namedargs:
- if arg != 'context' and arg in data and arg not in kwargs:
- kwargs[arg] = data[arg]
- return kwargs
- def _kwargs_for_include(callable_, data, **kwargs):
- argspec = compat.inspect_func_args(callable_)
- namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
- for arg in namedargs:
- if arg != 'context' and arg in data and arg not in kwargs:
- kwargs[arg] = data[arg]
- return kwargs
- def _render_context(tmpl, callable_, context, *args, **kwargs):
- import mako.template as template
- # create polymorphic 'self' namespace for this
- # template with possibly updated context
- if not isinstance(tmpl, template.DefTemplate):
- # if main render method, call from the base of the inheritance stack
- (inherit, lclcontext) = _populate_self_namespace(context, tmpl)
- _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
- else:
- # otherwise, call the actual rendering method specified
- (inherit, lclcontext) = _populate_self_namespace(context, tmpl.parent)
- _exec_template(callable_, context, args=args, kwargs=kwargs)
- def _exec_template(callable_, context, args=None, kwargs=None):
- """execute a rendering callable given the callable, a
- Context, and optional explicit arguments
- the contextual Template will be located if it exists, and
- the error handling options specified on that Template will
- be interpreted here.
- """
- template = context._with_template
- if template is not None and \
- (template.format_exceptions or template.error_handler):
- try:
- callable_(context, *args, **kwargs)
- except Exception:
- _render_error(template, context, compat.exception_as())
- except:
- e = sys.exc_info()[0]
- _render_error(template, context, e)
- else:
- callable_(context, *args, **kwargs)
- def _render_error(template, context, error):
- if template.error_handler:
- result = template.error_handler(context, error)
- if not result:
- compat.reraise(*sys.exc_info())
- else:
- error_template = exceptions.html_error_template()
- if context._outputting_as_unicode:
- context._buffer_stack[:] = [
- util.FastEncodingBuffer(as_unicode=True)]
- else:
- context._buffer_stack[:] = [util.FastEncodingBuffer(
- error_template.output_encoding,
- error_template.encoding_errors)]
- context._set_with_template(error_template)
- error_template.render_context(context, error=error)
|