diff --git a/mako/codegen.py b/mako/codegen.py
index e26f7f72b15beabe12397cb21552cba7ee470313..2af1eac7759a91adb7ce28f1842971312e8d6b7e 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 78c209f563ad2db8acc55f2ad1519577d52735e6..60c15520bcb99d0dfae342d4efa4e50cd2af5e2a 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