aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mako/codegen.py39
-rw-r--r--mako/runtime.py75
2 files changed, 80 insertions, 34 deletions
diff --git a/mako/codegen.py b/mako/codegen.py
index e26f7f7..2af1eac 100644
--- a/mako/codegen.py
+++ b/mako/codegen.py
@@ -11,7 +11,7 @@ import re
from mako.pygen import PythonPrinter
from mako import util, ast, parsetree, filters
-MAGIC_NUMBER = 5
+MAGIC_NUMBER = 6
def compile(node,
uri,
@@ -319,14 +319,35 @@ class _GenerateRenderMethod(object):
callable_name = "make_namespace()"
else:
callable_name = "None"
- self.printer.writeline(
- "ns = runtime.Namespace(%r, context._clean_inheritance_tokens(),"
- " templateuri=%s, callables=%s, calling_uri=_template_uri, module=%s)" %
- (
- node.name,
- node.parsed_attributes.get('file', 'None'),
- callable_name,
- node.parsed_attributes.get('module', 'None'))
+
+ if 'file' in node.parsed_attributes:
+ self.printer.writeline(
+ "ns = runtime.TemplateNamespace(%r, context._clean_inheritance_tokens(),"
+ " templateuri=%s, callables=%s, calling_uri=_template_uri)" %
+ (
+ node.name,
+ node.parsed_attributes.get('file', 'None'),
+ callable_name,
+ )
+ )
+ elif 'module' in node.parsed_attributes:
+ self.printer.writeline(
+ "ns = runtime.ModuleNamespace(%r, context._clean_inheritance_tokens(),"
+ " callables=%s, calling_uri=_template_uri, module=%s)" %
+ (
+ node.name,
+ callable_name,
+ node.parsed_attributes.get('module', 'None')
+ )
+ )
+ else:
+ self.printer.writeline(
+ "ns = runtime.Namespace(%r, context._clean_inheritance_tokens(),"
+ " callables=%s, calling_uri=_template_uri)" %
+ (
+ node.name,
+ callable_name,
+ )
)
if eval(node.attributes.get('inheritable', "False")):
self.printer.writeline("context['self'].%s = ns" % (node.name))
diff --git a/mako/runtime.py b/mako/runtime.py
index 78c209f..60c1552 100644
--- a/mako/runtime.py
+++ b/mako/runtime.py
@@ -210,35 +210,19 @@ class Namespace(object):
"""
- def __init__(self, name, context, module=None,
- template=None, templateuri=None,
+ def __init__(self, name, context,
callables=None, inherits=None,
populate_self=True, calling_uri=None):
self.name = name
- if module is not None:
- mod = __import__(module)
- for token in module.split('.')[1:]:
- mod = getattr(mod, token)
- self._module = mod
- else:
- self._module = None
- if templateuri is not None:
- self.template = _lookup_template(context, templateuri, calling_uri)
- self._templateuri = self.template.module._template_uri
- else:
- self.template = template
- if self.template is not None:
- self._templateuri = self.template.module._template_uri
self.context = context
self.inherits = inherits
if callables is not None:
self.callables = dict([(c.func_name, c) for c in callables])
- else:
- self.callables = None
- if populate_self and self.template is not None:
- lclcallable, lclcontext = \
- _populate_self_namespace(context, self.template, self_ns=self)
-
+
+ callables = None
+
+ _module = None
+
template = None
"""The :class:`.Template` object referenced by this
:class:`.Namespace`, if any.
@@ -333,7 +317,7 @@ class Namespace(object):
if self.context.namespaces.has_key(key):
return self.context.namespaces[key]
else:
- ns = Namespace(uri, self.context._copy(),
+ ns = TemplateNamespace(uri, self.context._copy(),
templateuri=uri,
calling_uri=self._templateuri)
self.context.namespaces[key] = ns
@@ -433,6 +417,47 @@ class Namespace(object):
"Namespace '%s' has no member '%s'" %
(self.name, key))
+class TemplateNamespace(Namespace):
+ 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.func_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)
+
+class ModuleNamespace(Namespace):
+ 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.func_name, c) for c in callables])
+
+ mod = __import__(module)
+ for token in module.split('.')[1:]:
+ mod = getattr(mod, token)
+ self._module = mod
+
+
def supports_caller(func):
"""Apply a caller_stack compatibility decorator to a plain
Python function.
@@ -514,7 +539,7 @@ def _inherit_from(context, uri, calling_uri):
while ih.inherits is not None:
ih = ih.inherits
lclcontext = context.locals_({'next':ih})
- ih.inherits = Namespace("self:%s" % template.uri,
+ ih.inherits = TemplateNamespace("self:%s" % template.uri,
lclcontext,
template = template,
populate_self=False)
@@ -544,7 +569,7 @@ def _lookup_template(context, uri, relativeto):
def _populate_self_namespace(context, template, self_ns=None):
if self_ns is None:
- self_ns = Namespace('self:%s' % template.uri,
+ self_ns = TemplateNamespace('self:%s' % template.uri,
context, template=template,
populate_self=False)
context._data['self'] = context._data['local'] = self_ns