[Checkins] SVN: zope.pagetemplate/trunk/ Workaround for CPU-burning pt_errors() on a recursive template.

Marius Gedminas cvs-admin at zope.org
Wed Dec 12 17:26:15 UTC 2012


Log message for revision 128621:
  Workaround for CPU-burning pt_errors() on a recursive template.
  
  See https://bugs.launchpad.net/zope.pagetemplate/+bug/732972
  
  This implements the short workaround version of the solution mentioned in the
  bug: let's skip macro expansion checking while we're formatting an error
  traceback (with the default recursion limit of 100 this still burns a lot of
  CPU: ~20 seconds on a 2.5 GHz Core i5).
  
  The test can be easily extended for the better suggested solution (some time in
  the future): just drop check_macro_expansion=False and make sure METAL silently
  stops recursing iff it notices a loop and TAL evaluation is disabled.
  
  

Changed:
  U   zope.pagetemplate/trunk/CHANGES.txt
  U   zope.pagetemplate/trunk/src/zope/pagetemplate/pagetemplate.py
  A   zope.pagetemplate/trunk/src/zope/pagetemplate/tests/input/recursive.html
  A   zope.pagetemplate/trunk/src/zope/pagetemplate/tests/output/recursive.html
  U   zope.pagetemplate/trunk/src/zope/pagetemplate/tests/test_htmltests.py

-=-
Modified: zope.pagetemplate/trunk/CHANGES.txt
===================================================================
--- zope.pagetemplate/trunk/CHANGES.txt	2012-12-12 14:41:04 UTC (rev 128620)
+++ zope.pagetemplate/trunk/CHANGES.txt	2012-12-12 17:26:15 UTC (rev 128621)
@@ -13,7 +13,13 @@
 
 - Dropped support for Python 2.4 and 2.5.
 
+- PageTemplate.pt_render() has a new argument, check_macro_expansion,
+  defaulting to True.
 
+- PageTemplateTracebackSupplement passes check_macro_expansion=False, to
+  avoid LP#732972.
+
+
 3.6.3 (2011-09-21)
 ------------------
 

Modified: zope.pagetemplate/trunk/src/zope/pagetemplate/pagetemplate.py
===================================================================
--- zope.pagetemplate/trunk/src/zope/pagetemplate/pagetemplate.py	2012-12-12 14:41:04 UTC (rev 128620)
+++ zope.pagetemplate/trunk/src/zope/pagetemplate/pagetemplate.py	2012-12-12 17:26:15 UTC (rev 128621)
@@ -132,15 +132,16 @@
             strictinsert=0, sourceAnnotations=sourceAnnotations
             )
 
-    def pt_errors(self, namespace):
+    def pt_errors(self, namespace, check_macro_expansion=True):
         self._cook_check()
         err = self._v_errors
         if err:
             return err
-        try:
-            self.pt_render(namespace, source=1)
-        except:
-            return ('Macro expansion failed', '%s: %s' % sys.exc_info()[:2])
+        if check_macro_expansion:
+            try:
+                self.pt_render(namespace, source=1)
+            except:
+                return ('Macro expansion failed', '%s: %s' % sys.exc_info()[:2])
 
     def write(self, text):
         # We accept both, since the text can either come from a file (and the
@@ -261,6 +262,6 @@
     def __init__(self, pt, namespace):
         self.manageable_object = pt
         self.warnings = []
-        e = pt.pt_errors(namespace)
+        e = pt.pt_errors(namespace, check_macro_expansion=False)
         if e:
             self.warnings.extend(e)

Added: zope.pagetemplate/trunk/src/zope/pagetemplate/tests/input/recursive.html
===================================================================
--- zope.pagetemplate/trunk/src/zope/pagetemplate/tests/input/recursive.html	                        (rev 0)
+++ zope.pagetemplate/trunk/src/zope/pagetemplate/tests/input/recursive.html	2012-12-12 17:26:15 UTC (rev 128621)
@@ -0,0 +1,7 @@
+<!-- See https://bugs.launchpad.net/zope.pagetemplate/+bug/732972 -->
+<ul metal:define-macro="tree">
+  <li tal:content="context/name" />
+  <li tal:repeat="context context/children">
+    <ul metal:use-macro="template/macros/tree" />
+  </li>
+</ul>

Added: zope.pagetemplate/trunk/src/zope/pagetemplate/tests/output/recursive.html
===================================================================
--- zope.pagetemplate/trunk/src/zope/pagetemplate/tests/output/recursive.html	                        (rev 0)
+++ zope.pagetemplate/trunk/src/zope/pagetemplate/tests/output/recursive.html	2012-12-12 17:26:15 UTC (rev 128621)
@@ -0,0 +1,14 @@
+<!-- See https://bugs.launchpad.net/zope.pagetemplate/+bug/732972 -->
+<ul>
+ <li>root</li>
+ <li>
+ <ul>
+ <li>first</li>
+</ul>
+ </li>
+ <li>
+ <ul>
+ <li>second</li>
+</ul>
+ </li>
+</ul>

Modified: zope.pagetemplate/trunk/src/zope/pagetemplate/tests/test_htmltests.py
===================================================================
--- zope.pagetemplate/trunk/src/zope/pagetemplate/tests/test_htmltests.py	2012-12-12 14:41:04 UTC (rev 128620)
+++ zope.pagetemplate/trunk/src/zope/pagetemplate/tests/test_htmltests.py	2012-12-12 17:26:15 UTC (rev 128621)
@@ -133,6 +133,20 @@
         out = t(msg=msg)
         util.check_html(expect, out)
 
+    def test_recursion(self):
+        t = self.folder.t
+        t.write(util.read_input('recursive.html'))
+        expect = util.read_output('recursive.html')
+        context = dict(name='root',
+                       children=[dict(name='first', children=[]),
+                                 dict(name='second', children=[])])
+        namespace = dict(template=t, options={}, args=(),
+                         nothing=None, context=context)
+        out = t.pt_render(namespace)
+        util.check_html(expect, out)
+        # https://bugs.launchpad.net/zope.pagetemplate/+bug/732972
+        errors = t.pt_errors(namespace, check_macro_expansion=False)
+        self.assertFalse(errors)
 
 def test_suite():
     return unittest.makeSuite(HTMLTests)



More information about the checkins mailing list