summaryrefslogtreecommitdiff
path: root/mako/runtime.py
diff options
context:
space:
mode:
Diffstat (limited to 'mako/runtime.py')
-rw-r--r--mako/runtime.py183
1 files changed, 117 insertions, 66 deletions
diff --git a/mako/runtime.py b/mako/runtime.py
index 769541c..8c4f78c 100644
--- a/mako/runtime.py
+++ b/mako/runtime.py
@@ -7,10 +7,13 @@
"""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
+from mako import compat
+from mako import exceptions
+from mako import util
+from mako.compat import compat_builtins
+
class Context(object):
@@ -34,18 +37,19 @@ class Context(object):
# "capture" function which proxies to the
# generic "capture" function
- self._data['capture'] = compat.partial(capture, self)
+ self._data["capture"] = compat.partial(capture, self)
# "caller" stack used by def calls with content
- self.caller_stack = self._data['caller'] = CallerStack()
+ 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))
+ "Reserved words passed to render(): %s"
+ % ", ".join(illegal_names)
+ )
@property
def lookup(self):
@@ -177,14 +181,13 @@ class Context(object):
c = self._copy()
x = c._data
- x.pop('self', None)
- x.pop('parent', None)
- x.pop('next', None)
+ x.pop("self", None)
+ x.pop("parent", None)
+ x.pop("next", None)
return c
class CallerStack(list):
-
def __init__(self):
self.nextcaller = None
@@ -231,6 +234,7 @@ class Undefined(object):
def __bool__(self):
return False
+
UNDEFINED = Undefined()
STOP_RENDERING = ""
@@ -342,7 +346,6 @@ class LoopContext(object):
class _NSAttr(object):
-
def __init__(self, parent):
self.__parent = parent
@@ -373,9 +376,15 @@ class Namespace(object):
"""
- def __init__(self, name, context,
- callables=None, inherits=None,
- populate_self=True, calling_uri=None):
+ def __init__(
+ self,
+ name,
+ context,
+ callables=None,
+ inherits=None,
+ populate_self=True,
+ calling_uri=None,
+ ):
self.name = name
self.context = context
self.inherits = inherits
@@ -473,9 +482,12 @@ class Namespace(object):
if key in self.context.namespaces:
return self.context.namespaces[key]
else:
- ns = TemplateNamespace(uri, self.context._copy(),
- templateuri=uri,
- calling_uri=self._templateuri)
+ ns = TemplateNamespace(
+ uri,
+ self.context._copy(),
+ templateuri=uri,
+ calling_uri=self._templateuri,
+ )
self.context.namespaces[key] = ns
return ns
@@ -518,7 +530,7 @@ class Namespace(object):
def _populate(self, d, l):
for ident in l:
- if ident == '*':
+ if ident == "*":
for (k, v) in self._get_star():
d[k] = v
else:
@@ -536,8 +548,8 @@ class Namespace(object):
val = getattr(self.inherits, key)
else:
raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
+ "Namespace '%s' has no member '%s'" % (self.name, key)
+ )
setattr(self, key, val)
return val
@@ -546,9 +558,17 @@ 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):
+ 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
@@ -556,8 +576,7 @@ class TemplateNamespace(Namespace):
self.callables = dict([(c.__name__, c) for c in callables])
if templateuri is not None:
- self.template = _lookup_template(context, templateuri,
- calling_uri)
+ self.template = _lookup_template(context, templateuri, calling_uri)
self._templateuri = self.template.module._template_uri
elif template is not None:
self.template = template
@@ -566,9 +585,9 @@ class TemplateNamespace(Namespace):
raise TypeError("'template' argument is required.")
if populate_self:
- lclcallable, lclcontext = \
- _populate_self_namespace(context, self.template,
- self_ns=self)
+ lclcallable, lclcontext = _populate_self_namespace(
+ context, self.template, self_ns=self
+ )
@property
def module(self):
@@ -607,6 +626,7 @@ class TemplateNamespace(Namespace):
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))
@@ -621,8 +641,8 @@ class TemplateNamespace(Namespace):
else:
raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
+ "Namespace '%s' has no member '%s'" % (self.name, key)
+ )
setattr(self, key, val)
return val
@@ -631,9 +651,16 @@ 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):
+ 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
@@ -641,7 +668,7 @@ class ModuleNamespace(Namespace):
self.callables = dict([(c.__name__, c) for c in callables])
mod = __import__(module)
- for token in module.split('.')[1:]:
+ for token in module.split(".")[1:]:
mod = getattr(mod, token)
self.module = mod
@@ -657,7 +684,7 @@ class ModuleNamespace(Namespace):
for key in self.callables:
yield (key, self.callables[key])
for key in dir(self.module):
- if key[0] != '_':
+ if key[0] != "_":
callable_ = getattr(self.module, key)
if compat.callable(callable_):
yield key, compat.partial(callable_, self.context)
@@ -672,8 +699,8 @@ class ModuleNamespace(Namespace):
val = getattr(self.inherits, key)
else:
raise AttributeError(
- "Namespace '%s' has no member '%s'" %
- (self.name, key))
+ "Namespace '%s' has no member '%s'" % (self.name, key)
+ )
setattr(self, key, val)
return val
@@ -692,6 +719,7 @@ def supports_caller(func):
return func(context, *args, **kwargs)
finally:
context.caller_stack._pop_frame()
+
return wrap_stackframe
@@ -721,13 +749,16 @@ def _decorate_toplevel(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
@@ -737,7 +768,9 @@ def _decorate_inline(context, fn):
def go(*args, **kw):
return dec(context, *args, **kw)
+
return go
+
return decorate_render
@@ -747,8 +780,8 @@ def _include_file(context, uri, calling_uri, **kwargs):
template = _lookup_template(context, uri, calling_uri)
(callable_, ctx) = _populate_self_namespace(
- context._clean_inheritance_tokens(),
- template)
+ context._clean_inheritance_tokens(), template
+ )
kwargs = _kwargs_for_include(callable_, context._data, **kwargs)
if template.include_error_handler:
try:
@@ -769,23 +802,25 @@ def _inherit_from(context, uri, calling_uri):
if uri is None:
return None
template = _lookup_template(context, uri, calling_uri)
- self_ns = context['self']
+ 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)
+ 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)
+ gen_ns = getattr(template.module, "_mako_generate_namespaces", None)
if gen_ns is not None:
gen_ns(context)
return (template.callable_, lclcontext)
@@ -795,8 +830,9 @@ 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)
+ "Template '%s' has no TemplateLookup associated"
+ % context._with_template.uri
+ )
uri = lookup.adjust_uri(uri, relativeto)
try:
return lookup.get_template(uri)
@@ -806,11 +842,14 @@ def _lookup_template(context, uri, relativeto):
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'):
+ 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
@@ -829,13 +868,19 @@ def _render(template, callable_, args, data, as_unicode=False):
buf = util.FastEncodingBuffer(
as_unicode=as_unicode,
encoding=template.output_encoding,
- errors=template.encoding_errors)
+ 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))
+ _render_context(
+ template,
+ callable_,
+ context,
+ *args,
+ **_kwargs_for_callable(callable_, data)
+ )
return context._pop_buffer().getvalue()
@@ -849,7 +894,7 @@ def _kwargs_for_callable(callable_, data):
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:
+ if arg != "context" and arg in data and arg not in kwargs:
kwargs[arg] = data[arg]
return kwargs
@@ -858,13 +903,14 @@ 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:
+ 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):
@@ -886,8 +932,9 @@ def _exec_template(callable_, context, args=None, kwargs=None):
be interpreted here.
"""
template = context._with_template
- if template is not None and \
- (template.format_exceptions or template.error_handler):
+ if template is not None and (
+ template.format_exceptions or template.error_handler
+ ):
try:
callable_(context, *args, **kwargs)
except Exception:
@@ -908,11 +955,15 @@ def _render_error(template, context, error):
error_template = exceptions.html_error_template()
if context._outputting_as_unicode:
context._buffer_stack[:] = [
- util.FastEncodingBuffer(as_unicode=True)]
+ util.FastEncodingBuffer(as_unicode=True)
+ ]
else:
- context._buffer_stack[:] = [util.FastEncodingBuffer(
- error_template.output_encoding,
- error_template.encoding_errors)]
+ 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)