Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/mako/runtime.py : 25%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# mako/runtime.py
2# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file>
3#
4# This module is part of Mako and is released under
5# the MIT License: http://www.opensource.org/licenses/mit-license.php
7"""provides runtime services for templates, including Context,
8Namespace, and various helper functions."""
10import functools
11import sys
13from mako import compat
14from mako import exceptions
15from mako import util
16from mako.compat import compat_builtins
19class Context(object):
21 """Provides runtime namespace, output buffer, and various
22 callstacks for templates.
24 See :ref:`runtime_toplevel` for detail on the usage of
25 :class:`.Context`.
27 """
29 def __init__(self, buffer, **data):
30 self._buffer_stack = [buffer]
32 self._data = data
34 self._kwargs = data.copy()
35 self._with_template = None
36 self._outputting_as_unicode = None
37 self.namespaces = {}
39 # "capture" function which proxies to the
40 # generic "capture" function
41 self._data["capture"] = functools.partial(capture, self)
43 # "caller" stack used by def calls with content
44 self.caller_stack = self._data["caller"] = CallerStack()
46 def _set_with_template(self, t):
47 self._with_template = t
48 illegal_names = t.reserved_names.intersection(self._data)
49 if illegal_names:
50 raise exceptions.NameConflictError(
51 "Reserved words passed to render(): %s"
52 % ", ".join(illegal_names)
53 )
55 @property
56 def lookup(self):
57 """Return the :class:`.TemplateLookup` associated
58 with this :class:`.Context`.
60 """
61 return self._with_template.lookup
63 @property
64 def kwargs(self):
65 """Return the dictionary of top level keyword arguments associated
66 with this :class:`.Context`.
68 This dictionary only includes the top-level arguments passed to
69 :meth:`.Template.render`. It does not include names produced within
70 the template execution such as local variable names or special names
71 such as ``self``, ``next``, etc.
73 The purpose of this dictionary is primarily for the case that
74 a :class:`.Template` accepts arguments via its ``<%page>`` tag,
75 which are normally expected to be passed via :meth:`.Template.render`,
76 except the template is being called in an inheritance context,
77 using the ``body()`` method. :attr:`.Context.kwargs` can then be
78 used to propagate these arguments to the inheriting template::
80 ${next.body(**context.kwargs)}
82 """
83 return self._kwargs.copy()
85 def push_caller(self, caller):
86 """Push a ``caller`` callable onto the callstack for
87 this :class:`.Context`."""
89 self.caller_stack.append(caller)
91 def pop_caller(self):
92 """Pop a ``caller`` callable onto the callstack for this
93 :class:`.Context`."""
95 del self.caller_stack[-1]
97 def keys(self):
98 """Return a list of all names established in this :class:`.Context`."""
100 return list(self._data.keys())
102 def __getitem__(self, key):
103 if key in self._data:
104 return self._data[key]
105 else:
106 return compat_builtins.__dict__[key]
108 def _push_writer(self):
109 """push a capturing buffer onto this Context and return
110 the new writer function."""
112 buf = util.FastEncodingBuffer()
113 self._buffer_stack.append(buf)
114 return buf.write
116 def _pop_buffer_and_writer(self):
117 """pop the most recent capturing buffer from this Context
118 and return the current writer after the pop.
120 """
122 buf = self._buffer_stack.pop()
123 return buf, self._buffer_stack[-1].write
125 def _push_buffer(self):
126 """push a capturing buffer onto this Context."""
128 self._push_writer()
130 def _pop_buffer(self):
131 """pop the most recent capturing buffer from this Context."""
133 return self._buffer_stack.pop()
135 def get(self, key, default=None):
136 """Return a value from this :class:`.Context`."""
138 return self._data.get(key, compat_builtins.__dict__.get(key, default))
140 def write(self, string):
141 """Write a string to this :class:`.Context` object's
142 underlying output buffer."""
144 self._buffer_stack[-1].write(string)
146 def writer(self):
147 """Return the current writer function."""
149 return self._buffer_stack[-1].write
151 def _copy(self):
152 c = Context.__new__(Context)
153 c._buffer_stack = self._buffer_stack
154 c._data = self._data.copy()
155 c._kwargs = self._kwargs
156 c._with_template = self._with_template
157 c._outputting_as_unicode = self._outputting_as_unicode
158 c.namespaces = self.namespaces
159 c.caller_stack = self.caller_stack
160 return c
162 def _locals(self, d):
163 """Create a new :class:`.Context` with a copy of this
164 :class:`.Context`'s current state,
165 updated with the given dictionary.
167 The :attr:`.Context.kwargs` collection remains
168 unaffected.
171 """
173 if not d:
174 return self
175 c = self._copy()
176 c._data.update(d)
177 return c
179 def _clean_inheritance_tokens(self):
180 """create a new copy of this :class:`.Context`. with
181 tokens related to inheritance state removed."""
183 c = self._copy()
184 x = c._data
185 x.pop("self", None)
186 x.pop("parent", None)
187 x.pop("next", None)
188 return c
191class CallerStack(list):
192 def __init__(self):
193 self.nextcaller = None
195 def __nonzero__(self):
196 return self.__bool__()
198 def __bool__(self):
199 return len(self) and self._get_caller() and True or False
201 def _get_caller(self):
202 # this method can be removed once
203 # codegen MAGIC_NUMBER moves past 7
204 return self[-1]
206 def __getattr__(self, key):
207 return getattr(self._get_caller(), key)
209 def _push_frame(self):
210 frame = self.nextcaller or None
211 self.append(frame)
212 self.nextcaller = None
213 return frame
215 def _pop_frame(self):
216 self.nextcaller = self.pop()
219class Undefined(object):
221 """Represents an undefined value in a template.
223 All template modules have a constant value
224 ``UNDEFINED`` present which is an instance of this
225 object.
227 """
229 def __str__(self):
230 raise NameError("Undefined")
232 def __nonzero__(self):
233 return self.__bool__()
235 def __bool__(self):
236 return False
239UNDEFINED = Undefined()
240STOP_RENDERING = ""
243class LoopStack(object):
245 """a stack for LoopContexts that implements the context manager protocol
246 to automatically pop off the top of the stack on context exit
247 """
249 def __init__(self):
250 self.stack = []
252 def _enter(self, iterable):
253 self._push(iterable)
254 return self._top
256 def _exit(self):
257 self._pop()
258 return self._top
260 @property
261 def _top(self):
262 if self.stack:
263 return self.stack[-1]
264 else:
265 return self
267 def _pop(self):
268 return self.stack.pop()
270 def _push(self, iterable):
271 new = LoopContext(iterable)
272 if self.stack:
273 new.parent = self.stack[-1]
274 return self.stack.append(new)
276 def __getattr__(self, key):
277 raise exceptions.RuntimeException("No loop context is established")
279 def __iter__(self):
280 return iter(self._top)
283class LoopContext(object):
285 """A magic loop variable.
286 Automatically accessible in any ``% for`` block.
288 See the section :ref:`loop_context` for usage
289 notes.
291 :attr:`parent` -> :class:`.LoopContext` or ``None``
292 The parent loop, if one exists.
293 :attr:`index` -> `int`
294 The 0-based iteration count.
295 :attr:`reverse_index` -> `int`
296 The number of iterations remaining.
297 :attr:`first` -> `bool`
298 ``True`` on the first iteration, ``False`` otherwise.
299 :attr:`last` -> `bool`
300 ``True`` on the last iteration, ``False`` otherwise.
301 :attr:`even` -> `bool`
302 ``True`` when ``index`` is even.
303 :attr:`odd` -> `bool`
304 ``True`` when ``index`` is odd.
305 """
307 def __init__(self, iterable):
308 self._iterable = iterable
309 self.index = 0
310 self.parent = None
312 def __iter__(self):
313 for i in self._iterable:
314 yield i
315 self.index += 1
317 @util.memoized_instancemethod
318 def __len__(self):
319 return len(self._iterable)
321 @property
322 def reverse_index(self):
323 return len(self) - self.index - 1
325 @property
326 def first(self):
327 return self.index == 0
329 @property
330 def last(self):
331 return self.index == len(self) - 1
333 @property
334 def even(self):
335 return not self.odd
337 @property
338 def odd(self):
339 return bool(self.index % 2)
341 def cycle(self, *values):
342 """Cycle through values as the loop progresses.
343 """
344 if not values:
345 raise ValueError("You must provide values to cycle through")
346 return values[self.index % len(values)]
349class _NSAttr(object):
350 def __init__(self, parent):
351 self.__parent = parent
353 def __getattr__(self, key):
354 ns = self.__parent
355 while ns:
356 if hasattr(ns.module, key):
357 return getattr(ns.module, key)
358 else:
359 ns = ns.inherits
360 raise AttributeError(key)
363class Namespace(object):
365 """Provides access to collections of rendering methods, which
366 can be local, from other templates, or from imported modules.
368 To access a particular rendering method referenced by a
369 :class:`.Namespace`, use plain attribute access:
371 .. sourcecode:: mako
373 ${some_namespace.foo(x, y, z)}
375 :class:`.Namespace` also contains several built-in attributes
376 described here.
378 """
380 def __init__(
381 self,
382 name,
383 context,
384 callables=None,
385 inherits=None,
386 populate_self=True,
387 calling_uri=None,
388 ):
389 self.name = name
390 self.context = context
391 self.inherits = inherits
392 if callables is not None:
393 self.callables = dict([(c.__name__, c) for c in callables])
395 callables = ()
397 module = None
398 """The Python module referenced by this :class:`.Namespace`.
400 If the namespace references a :class:`.Template`, then
401 this module is the equivalent of ``template.module``,
402 i.e. the generated module for the template.
404 """
406 template = None
407 """The :class:`.Template` object referenced by this
408 :class:`.Namespace`, if any.
410 """
412 context = None
413 """The :class:`.Context` object for this :class:`.Namespace`.
415 Namespaces are often created with copies of contexts that
416 contain slightly different data, particularly in inheritance
417 scenarios. Using the :class:`.Context` off of a :class:`.Namespace` one
418 can traverse an entire chain of templates that inherit from
419 one-another.
421 """
423 filename = None
424 """The path of the filesystem file used for this
425 :class:`.Namespace`'s module or template.
427 If this is a pure module-based
428 :class:`.Namespace`, this evaluates to ``module.__file__``. If a
429 template-based namespace, it evaluates to the original
430 template file location.
432 """
434 uri = None
435 """The URI for this :class:`.Namespace`'s template.
437 I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`.
439 This is the equivalent of :attr:`.Template.uri`.
441 """
443 _templateuri = None
445 @util.memoized_property
446 def attr(self):
447 """Access module level attributes by name.
449 This accessor allows templates to supply "scalar"
450 attributes which are particularly handy in inheritance
451 relationships.
453 .. seealso::
455 :ref:`inheritance_attr`
457 :ref:`namespace_attr_for_includes`
459 """
460 return _NSAttr(self)
462 def get_namespace(self, uri):
463 """Return a :class:`.Namespace` corresponding to the given ``uri``.
465 If the given ``uri`` is a relative URI (i.e. it does not
466 contain a leading slash ``/``), the ``uri`` is adjusted to
467 be relative to the ``uri`` of the namespace itself. This
468 method is therefore mostly useful off of the built-in
469 ``local`` namespace, described in :ref:`namespace_local`.
471 In
472 most cases, a template wouldn't need this function, and
473 should instead use the ``<%namespace>`` tag to load
474 namespaces. However, since all ``<%namespace>`` tags are
475 evaluated before the body of a template ever runs,
476 this method can be used to locate namespaces using
477 expressions that were generated within the body code of
478 the template, or to conditionally use a particular
479 namespace.
481 """
482 key = (self, uri)
483 if key in self.context.namespaces:
484 return self.context.namespaces[key]
485 else:
486 ns = TemplateNamespace(
487 uri,
488 self.context._copy(),
489 templateuri=uri,
490 calling_uri=self._templateuri,
491 )
492 self.context.namespaces[key] = ns
493 return ns
495 def get_template(self, uri):
496 """Return a :class:`.Template` from the given ``uri``.
498 The ``uri`` resolution is relative to the ``uri`` of this
499 :class:`.Namespace` object's :class:`.Template`.
501 """
502 return _lookup_template(self.context, uri, self._templateuri)
504 def get_cached(self, key, **kwargs):
505 """Return a value from the :class:`.Cache` referenced by this
506 :class:`.Namespace` object's :class:`.Template`.
508 The advantage to this method versus direct access to the
509 :class:`.Cache` is that the configuration parameters
510 declared in ``<%page>`` take effect here, thereby calling
511 up the same configured backend as that configured
512 by ``<%page>``.
514 """
516 return self.cache.get(key, **kwargs)
518 @property
519 def cache(self):
520 """Return the :class:`.Cache` object referenced
521 by this :class:`.Namespace` object's
522 :class:`.Template`.
524 """
525 return self.template.cache
527 def include_file(self, uri, **kwargs):
528 """Include a file at the given ``uri``."""
530 _include_file(self.context, uri, self._templateuri, **kwargs)
532 def _populate(self, d, l):
533 for ident in l:
534 if ident == "*":
535 for (k, v) in self._get_star():
536 d[k] = v
537 else:
538 d[ident] = getattr(self, ident)
540 def _get_star(self):
541 if self.callables:
542 for key in self.callables:
543 yield (key, self.callables[key])
545 def __getattr__(self, key):
546 if key in self.callables:
547 val = self.callables[key]
548 elif self.inherits:
549 val = getattr(self.inherits, key)
550 else:
551 raise AttributeError(
552 "Namespace '%s' has no member '%s'" % (self.name, key)
553 )
554 setattr(self, key, val)
555 return val
558class TemplateNamespace(Namespace):
560 """A :class:`.Namespace` specific to a :class:`.Template` instance."""
562 def __init__(
563 self,
564 name,
565 context,
566 template=None,
567 templateuri=None,
568 callables=None,
569 inherits=None,
570 populate_self=True,
571 calling_uri=None,
572 ):
573 self.name = name
574 self.context = context
575 self.inherits = inherits
576 if callables is not None:
577 self.callables = dict([(c.__name__, c) for c in callables])
579 if templateuri is not None:
580 self.template = _lookup_template(context, templateuri, calling_uri)
581 self._templateuri = self.template.module._template_uri
582 elif template is not None:
583 self.template = template
584 self._templateuri = template.module._template_uri
585 else:
586 raise TypeError("'template' argument is required.")
588 if populate_self:
589 lclcallable, lclcontext = _populate_self_namespace(
590 context, self.template, self_ns=self
591 )
593 @property
594 def module(self):
595 """The Python module referenced by this :class:`.Namespace`.
597 If the namespace references a :class:`.Template`, then
598 this module is the equivalent of ``template.module``,
599 i.e. the generated module for the template.
601 """
602 return self.template.module
604 @property
605 def filename(self):
606 """The path of the filesystem file used for this
607 :class:`.Namespace`'s module or template.
608 """
609 return self.template.filename
611 @property
612 def uri(self):
613 """The URI for this :class:`.Namespace`'s template.
615 I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`.
617 This is the equivalent of :attr:`.Template.uri`.
619 """
620 return self.template.uri
622 def _get_star(self):
623 if self.callables:
624 for key in self.callables:
625 yield (key, self.callables[key])
627 def get(key):
628 callable_ = self.template._get_def_callable(key)
629 return functools.partial(callable_, self.context)
631 for k in self.template.module._exports:
632 yield (k, get(k))
634 def __getattr__(self, key):
635 if key in self.callables:
636 val = self.callables[key]
637 elif self.template.has_def(key):
638 callable_ = self.template._get_def_callable(key)
639 val = functools.partial(callable_, self.context)
640 elif self.inherits:
641 val = getattr(self.inherits, key)
643 else:
644 raise AttributeError(
645 "Namespace '%s' has no member '%s'" % (self.name, key)
646 )
647 setattr(self, key, val)
648 return val
651class ModuleNamespace(Namespace):
653 """A :class:`.Namespace` specific to a Python module instance."""
655 def __init__(
656 self,
657 name,
658 context,
659 module,
660 callables=None,
661 inherits=None,
662 populate_self=True,
663 calling_uri=None,
664 ):
665 self.name = name
666 self.context = context
667 self.inherits = inherits
668 if callables is not None:
669 self.callables = dict([(c.__name__, c) for c in callables])
671 mod = __import__(module)
672 for token in module.split(".")[1:]:
673 mod = getattr(mod, token)
674 self.module = mod
676 @property
677 def filename(self):
678 """The path of the filesystem file used for this
679 :class:`.Namespace`'s module or template.
680 """
681 return self.module.__file__
683 def _get_star(self):
684 if self.callables:
685 for key in self.callables:
686 yield (key, self.callables[key])
687 for key in dir(self.module):
688 if key[0] != "_":
689 callable_ = getattr(self.module, key)
690 if callable(callable_):
691 yield key, functools.partial(callable_, self.context)
693 def __getattr__(self, key):
694 if key in self.callables:
695 val = self.callables[key]
696 elif hasattr(self.module, key):
697 callable_ = getattr(self.module, key)
698 val = functools.partial(callable_, self.context)
699 elif self.inherits:
700 val = getattr(self.inherits, key)
701 else:
702 raise AttributeError(
703 "Namespace '%s' has no member '%s'" % (self.name, key)
704 )
705 setattr(self, key, val)
706 return val
709def supports_caller(func):
710 """Apply a caller_stack compatibility decorator to a plain
711 Python function.
713 See the example in :ref:`namespaces_python_modules`.
715 """
717 def wrap_stackframe(context, *args, **kwargs):
718 context.caller_stack._push_frame()
719 try:
720 return func(context, *args, **kwargs)
721 finally:
722 context.caller_stack._pop_frame()
724 return wrap_stackframe
727def capture(context, callable_, *args, **kwargs):
728 """Execute the given template def, capturing the output into
729 a buffer.
731 See the example in :ref:`namespaces_python_modules`.
733 """
735 if not callable(callable_):
736 raise exceptions.RuntimeException(
737 "capture() function expects a callable as "
738 "its argument (i.e. capture(func, *args, **kwargs))"
739 )
740 context._push_buffer()
741 try:
742 callable_(*args, **kwargs)
743 finally:
744 buf = context._pop_buffer()
745 return buf.getvalue()
748def _decorate_toplevel(fn):
749 def decorate_render(render_fn):
750 def go(context, *args, **kw):
751 def y(*args, **kw):
752 return render_fn(context, *args, **kw)
754 try:
755 y.__name__ = render_fn.__name__[7:]
756 except TypeError:
757 # < Python 2.4
758 pass
759 return fn(y)(context, *args, **kw)
761 return go
763 return decorate_render
766def _decorate_inline(context, fn):
767 def decorate_render(render_fn):
768 dec = fn(render_fn)
770 def go(*args, **kw):
771 return dec(context, *args, **kw)
773 return go
775 return decorate_render
778def _include_file(context, uri, calling_uri, **kwargs):
779 """locate the template from the given uri and include it in
780 the current output."""
782 template = _lookup_template(context, uri, calling_uri)
783 (callable_, ctx) = _populate_self_namespace(
784 context._clean_inheritance_tokens(), template
785 )
786 kwargs = _kwargs_for_include(callable_, context._data, **kwargs)
787 if template.include_error_handler:
788 try:
789 callable_(ctx, **kwargs)
790 except Exception:
791 result = template.include_error_handler(ctx, compat.exception_as())
792 if not result:
793 compat.reraise(*sys.exc_info())
794 else:
795 callable_(ctx, **kwargs)
798def _inherit_from(context, uri, calling_uri):
799 """called by the _inherit method in template modules to set
800 up the inheritance chain at the start of a template's
801 execution."""
803 if uri is None:
804 return None
805 template = _lookup_template(context, uri, calling_uri)
806 self_ns = context["self"]
807 ih = self_ns
808 while ih.inherits is not None:
809 ih = ih.inherits
810 lclcontext = context._locals({"next": ih})
811 ih.inherits = TemplateNamespace(
812 "self:%s" % template.uri,
813 lclcontext,
814 template=template,
815 populate_self=False,
816 )
817 context._data["parent"] = lclcontext._data["local"] = ih.inherits
818 callable_ = getattr(template.module, "_mako_inherit", None)
819 if callable_ is not None:
820 ret = callable_(template, lclcontext)
821 if ret:
822 return ret
824 gen_ns = getattr(template.module, "_mako_generate_namespaces", None)
825 if gen_ns is not None:
826 gen_ns(context)
827 return (template.callable_, lclcontext)
830def _lookup_template(context, uri, relativeto):
831 lookup = context._with_template.lookup
832 if lookup is None:
833 raise exceptions.TemplateLookupException(
834 "Template '%s' has no TemplateLookup associated"
835 % context._with_template.uri
836 )
837 uri = lookup.adjust_uri(uri, relativeto)
838 try:
839 return lookup.get_template(uri)
840 except exceptions.TopLevelLookupException:
841 raise exceptions.TemplateLookupException(str(compat.exception_as()))
844def _populate_self_namespace(context, template, self_ns=None):
845 if self_ns is None:
846 self_ns = TemplateNamespace(
847 "self:%s" % template.uri,
848 context,
849 template=template,
850 populate_self=False,
851 )
852 context._data["self"] = context._data["local"] = self_ns
853 if hasattr(template.module, "_mako_inherit"):
854 ret = template.module._mako_inherit(template, context)
855 if ret:
856 return ret
857 return (template.callable_, context)
860def _render(template, callable_, args, data, as_unicode=False):
861 """create a Context and return the string
862 output of the given template and template callable."""
864 if as_unicode:
865 buf = util.FastEncodingBuffer(as_unicode=True)
866 elif template.bytestring_passthrough:
867 buf = compat.StringIO()
868 else:
869 buf = util.FastEncodingBuffer(
870 as_unicode=as_unicode,
871 encoding=template.output_encoding,
872 errors=template.encoding_errors,
873 )
874 context = Context(buf, **data)
875 context._outputting_as_unicode = as_unicode
876 context._set_with_template(template)
878 _render_context(
879 template,
880 callable_,
881 context,
882 *args,
883 **_kwargs_for_callable(callable_, data)
884 )
885 return context._pop_buffer().getvalue()
888def _kwargs_for_callable(callable_, data):
889 argspec = compat.inspect_getargspec(callable_)
890 # for normal pages, **pageargs is usually present
891 if argspec[2]:
892 return data
894 # for rendering defs from the top level, figure out the args
895 namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
896 kwargs = {}
897 for arg in namedargs:
898 if arg != "context" and arg in data and arg not in kwargs:
899 kwargs[arg] = data[arg]
900 return kwargs
903def _kwargs_for_include(callable_, data, **kwargs):
904 argspec = compat.inspect_getargspec(callable_)
905 namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
906 for arg in namedargs:
907 if arg != "context" and arg in data and arg not in kwargs:
908 kwargs[arg] = data[arg]
909 return kwargs
912def _render_context(tmpl, callable_, context, *args, **kwargs):
913 import mako.template as template
915 # create polymorphic 'self' namespace for this
916 # template with possibly updated context
917 if not isinstance(tmpl, template.DefTemplate):
918 # if main render method, call from the base of the inheritance stack
919 (inherit, lclcontext) = _populate_self_namespace(context, tmpl)
920 _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
921 else:
922 # otherwise, call the actual rendering method specified
923 (inherit, lclcontext) = _populate_self_namespace(context, tmpl.parent)
924 _exec_template(callable_, context, args=args, kwargs=kwargs)
927def _exec_template(callable_, context, args=None, kwargs=None):
928 """execute a rendering callable given the callable, a
929 Context, and optional explicit arguments
931 the contextual Template will be located if it exists, and
932 the error handling options specified on that Template will
933 be interpreted here.
934 """
935 template = context._with_template
936 if template is not None and (
937 template.format_exceptions or template.error_handler
938 ):
939 try:
940 callable_(context, *args, **kwargs)
941 except Exception:
942 _render_error(template, context, compat.exception_as())
943 except:
944 e = sys.exc_info()[0]
945 _render_error(template, context, e)
946 else:
947 callable_(context, *args, **kwargs)
950def _render_error(template, context, error):
951 if template.error_handler:
952 result = template.error_handler(context, error)
953 if not result:
954 compat.reraise(*sys.exc_info())
955 else:
956 error_template = exceptions.html_error_template()
957 if context._outputting_as_unicode:
958 context._buffer_stack[:] = [
959 util.FastEncodingBuffer(as_unicode=True)
960 ]
961 else:
962 context._buffer_stack[:] = [
963 util.FastEncodingBuffer(
964 error_template.output_encoding,
965 error_template.encoding_errors,
966 )
967 ]
969 context._set_with_template(error_template)
970 error_template.render_context(context, error=error)