Index: kidsupport.py
===================================================================
--- kidsupport.py	(Revision 2581)
+++ kidsupport.py	(Arbeitskopie)
@@ -32,7 +32,7 @@
 class KidSupport(object):
     #XXX: Is itertools.count threadsafe?
     string_template_serial = itertools.count()
-
+
     def __init__(self, extra_vars_func=None, options=None):
         if options is None:
             options = dict()
@@ -43,25 +43,25 @@
         self.sitetemplate = None
         self.stname = options.get("kid.sitetemplate", None)
         self.compiled_templates = {}
-
+
     def load_template_string(self, template_string):
         assert isinstance(template_string, basestring)
         tempclass = kid.load_template(
-            template_string,
+            template_string,
             name = "KidTemplateFromString-%d" % self.string_template_serial.next()
             ).Template
         tempclass.serializer = self.serializer
         return tempclass
-
+
     def load_template(self, classname=None, template_string=None, loadingSite=False):
         """Searches for a template along the Python path.
-
+
         Template files must end in ".kid" and be in legitimate packages.
         If the templates are precompiled to ".pyc" files, you can
-        set the "kid.precompiled" option to
+        set the "kid.precompiled" option to
         just do a straight import of the template.
         """
-
+
         if template_string is not None:
             return self.load_template_string(template_string)
         elif classname is None:
@@ -73,17 +73,21 @@
                 self.load_template(self.stname, loadingSite=True)
                 sys.modules["sitetemplate"] = sys.modules[self.stname]
                 self.sitetemplate = sys.modules["sitetemplate"]
-
+
         divider = classname.rfind(".")
         if divider > -1:
             package = classname[0:divider]
             basename = classname[divider+1:]
         else:
             raise ValueError, "All templates must be in a package"
-
-        if not self.options.get("kid.precompiled", False):
-            tfile = pkg_resources.resource_filename(package,
-                                                    "%s.kid" % basename)
+
+        if self.options.get("kid.precompiled", False):
+            # Always use the precompiled template since this is what
+            # the config says.
+            mod = __import__(classname, dict(), dict(), [basename])
+        else:
+            tfile = pkg_resources.resource_filename(
+                package, "%s.kid" % basename)
             ct = self.compiled_templates
             if sys.modules.has_key(classname) and ct.has_key(classname):
                 # This means that in sys.modules there is already the compiled
@@ -92,32 +96,32 @@
                 # In this case we may need to recompile because the template
                 # itself or one of its bases could have been modified.
                 tclass = sys.modules[classname].Template
-                involved_modules = [classname] + _get_extended_modules(tclass)
-                # Check the status of every involved module, if the module has
-                # been modified remove it from sys.modules, update its mtime
-                # and set to True the reload_template flag.
-                reload_template = False
-                for module in involved_modules:
+                ttime = ct[classname]
+                mtime = os.stat(sys.modules[classname].__file__).st_mtime
+                reload_template = mtime > ttime
+                if reload_template:
+                    ttime = mtime
+                # Check the status of all base moduls.
+                for module in _get_extended_modules(tclass):
                     mtime = os.stat(sys.modules[module].__file__).st_mtime
-                    if ct[module] != mtime:
+                    if mtime > ct[module]:
+                        # base template has changed
                         del sys.modules[module]
                         ct[module] = mtime
                         reload_template = True
-
+                    if mtime > ttime:
+                        # base module has changed
+                        reload_template = True
+                        ttime = mtime
                 if reload_template:
                     # We need to recompile the template.
                     log.debug("Recompiling template for %s" % classname)
-                    # If the template module is still in sys.modules (this
-                    # means that the template has not been modified but one or
-                    # more of its base templates have been) remove it
-                    # otherwise Kid will not recompile the removed bases
-                    # templates giving us a NoneType error.
-                    if sys.modules.has_key(classname):
-                        del sys.modules[classname]
-                    mod = _compile_template(package, basename,
-                                            tfile, classname)
+                    del sys.modules[classname]
+                    ct[classname] = ttime
+                    mod = _compile_template(
+                        package, basename, tfile, classname)
                 else:
-                    # No need to recompile the template or its bases,
+                    # No need to recompile the template or its bases,
                     # just reuse the existing modules.
                     mod = __import__(classname, dict(), dict(), [basename])
             else:
@@ -127,13 +131,14 @@
                 log.debug("Compiling template for %s" % classname)
                 mod = _compile_template(package, basename, tfile, classname)
                 tclass = mod.Template
-                involved_modules = [classname] + _get_extended_modules(tclass)
-                for module in involved_modules:
-                    ct[module] = os.stat(sys.modules[module].__file__).st_mtime
-        else:
-            # Always use the precompiled template since this is what
-            # the config says.
-            mod = __import__(classname, dict(), dict(), [basename])
+                ttime = os.stat(sys.modules[classname].__file__).st_mtime
+                for module in _get_extended_modules(tclass):
+                    mtime = os.stat(sys.modules[module].__file__).st_mtime
+                    ct[module] = mtime
+                    if mtime > ttime:
+                        ttime = mtime
+                # Store max of mtimes of template and all of its bases
+                ct[classname] = ttime

         tempclass = mod.Template
         tempclass.serializer = self.serializer
@@ -141,7 +146,7 @@

     def render(self, info, format="html", fragment=False, template=None):
         """Renders data in the desired format.
-
+
         @param info: the data itself
         @type info: dict
         @param format: "html", "xml" or "json"
@@ -170,7 +175,7 @@
             t.assume_encoding = options.get("kid.assume_encoding", "utf-8")
         if options.get("kid.i18n.run_template_filter", False):
             t._filters+=[options.get("kid.i18n_filter")]
-
+
         return t.serialize(encoding=self.defaultencoding, output=format, fragment=fragment)

     def transform(self, info, template):
@@ -182,11 +187,10 @@
         if self.get_extra_vars:
             data.update(self.get_extra_vars())
         data.update(info)
-
+
         t = tclass(**data)
-
+
         options = self.options
         if options.get("kid.i18n.run_template_filter", False):
             t._filters+=[options.get("kid.i18n_filter")]
         return ElementStream(t.transform()).expand()
-

