diff --git a/mako/parsetree.py b/mako/parsetree.py index 3ef85e6c13d72a9e7c9e05d6ad4a5cd45647f6dc..53a980d7b918ad430d5f45ff4e179a65ce41fa38 100644 --- a/mako/parsetree.py +++ b/mako/parsetree.py @@ -361,9 +361,14 @@ class NamespaceTag(Tag): self.name = attributes.get('name', '__anon_%s' % hex(abs(id(self)))) if not 'name' in attributes and not 'import' in attributes: raise exceptions.CompileException( - "'name' and/or 'import' attributes are required " - "for <%namespace>", - **self.exception_kwargs) + "'name' and/or 'import' attributes are required " + "for <%namespace>", + **self.exception_kwargs) + if 'file' in attributes and 'module' in attributes: + raise exceptions.CompileException( + "<%namespace> may only have one of 'file' or 'module'", + **self.exception_kwargs + ) def declared_identifiers(self): return [] diff --git a/mako/runtime.py b/mako/runtime.py index 42707e4ac9e23163686ec1c6b5a81d4ca8a6a2dd..e0df124b8eacf37e20ea0459bd64b792d18b5bed 100644 --- a/mako/runtime.py +++ b/mako/runtime.py @@ -302,7 +302,7 @@ class Namespace(object): """ key = (self, uri) - if key in self.context.namepaces: + if key in self.context.namespaces: return self.context.namespaces[key] else: ns = TemplateNamespace(uri, self.context._copy(), @@ -374,22 +374,12 @@ class Namespace(object): 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) - - elif self.template and self.template.has_def(key): - callable_ = self.template._get_def_callable(key) - val = util.partial(callable_, self.context) - - elif self.module and hasattr(self.module, key): - callable_ = getattr(self._module, key) - val = util.partial(callable_, self.context) - else: raise AttributeError( "Namespace '%s' has no member '%s'" % @@ -463,6 +453,21 @@ class TemplateNamespace(Namespace): 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 = util.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.""" @@ -499,6 +504,21 @@ class ModuleNamespace(Namespace): if k[0] != '_': yield (k, get(k)) + def __getattr__(self, key): + if key in self.callables: + val = self.callables[key] + elif hasattr(self.module, key): + callable_ = getattr(self.module, key) + val = util.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. diff --git a/test/test_def.py b/test/test_def.py index 00f904c805edb0a43fe2804365533fefc3de0366..3ec63ff8813dc74b7e430a723e0364c44124630a 100644 --- a/test/test_def.py +++ b/test/test_def.py @@ -367,9 +367,7 @@ class ScopeTest(TemplateTest): """) # test via inheritance - print l.get_template("main").code - import pdb - pdb.set_trace() + #print l.get_template("main").code assert result_lines(l.get_template("main").render()) == [ "this is main. x is 12", "this is a, x is 12"