[Checkins] SVN: z3c.pt/trunk/ Avoid storing stream-object; instead, we store a copy of the source-code and the symbol mappings.

Malthe Borch mborch at gmail.com
Tue Sep 9 09:39:44 EDT 2008


Log message for revision 90999:
  Avoid storing stream-object; instead, we store a copy of the source-code and the symbol mappings.

Changed:
  U   z3c.pt/trunk/CHANGES.txt
  U   z3c.pt/trunk/src/z3c/pt/translation.py

-=-
Modified: z3c.pt/trunk/CHANGES.txt
===================================================================
--- z3c.pt/trunk/CHANGES.txt	2008-09-09 13:38:49 UTC (rev 90998)
+++ z3c.pt/trunk/CHANGES.txt	2008-09-09 13:39:44 UTC (rev 90999)
@@ -167,6 +167,9 @@
 
   Bugfixes
 
+- Fixed an issue related to correct restoring of ghosted template
+  objects. [malthe]
+
 - Implicit doctype is correctly reestablished from cache. [malthe]
 
 - Remove namespace declaration on root tag to work around syntax error

Modified: z3c.pt/trunk/src/z3c/pt/translation.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-09 13:38:49 UTC (rev 90998)
+++ z3c.pt/trunk/src/z3c/pt/translation.py	2008-09-09 13:39:44 UTC (rev 90999)
@@ -528,6 +528,7 @@
     doctype regardless of what the template defines."""
 
     doctype = None
+    implicit_doctype = ""
     
     def __init__(self, body, parser, implicit_doctype=None, explicit_doctype=None):
         # if no doctype is defined, prepend the implicit doctype to
@@ -541,9 +542,9 @@
             implicit_doctype = implicit_doctype[:-1] + '  [ %s ]>' % entities
 
             # prepend to body
+            self.implicit_doctype = implicit_doctype
             body = implicit_doctype + "\n" + body
             
-        self.xmldoc = body
         self.root, parsed_doctype = parser.parse(body)
 
         if explicit_doctype is not None:
@@ -614,6 +615,10 @@
         self.root.start(stream)
         body = stream.getvalue()
 
+        # remove namespace declaration
+        if 'xmlns' in self.root.attrib:
+            del self.root.attrib['xmlns']
+        
         # prepare args
         ignore = 'target_language',
         args = ', '.join((param for param in params if param not in ignore))
@@ -635,36 +640,34 @@
             args=args, kwargs=kwargs, extra=extra, body=body)
         mapping.update(stream.symbols.__dict__)
         source = wrapper % mapping
-        
-        # set symbol mappings as globals
-        _globals = stream.symbol_mapping
-        
+
+        # serialize document
+        xmldoc = self.implicit_doctype + "\n" + self.root.tostring()
+
+        return ByteCodeTemplate(
+            source, stream.symbol_mapping,
+            xmldoc, self.parser, self.root)
+
+class ByteCodeTemplate(object):
+    """Template compiled to byte-code."""
+
+    def __init__(self, source, symbols, xmldoc, parser, tree):
         # compile code
-        suite = codegen.Suite(source, globals=_globals)
-        suite._globals.update(_globals)
+        suite = codegen.Suite(source, globals=symbols)
+        suite._globals.update(symbols)
         
         # execute code
         _locals = {}
         exec suite.code in suite._globals, _locals
-        render = _locals['render']
 
-        # remove namespace declaration
-        if 'xmlns' in self.root.attrib:
-            del self.root.attrib['xmlns']
-        
-        return ByteCodeTemplate(
-            render, stream, self.xmldoc, self.parser, self.root)
-
-class ByteCodeTemplate(object):
-    """Template compiled to byte-code."""
-
-    def __init__(self, func, stream, xmldoc, parser, tree):
-        self.func = func
-        self.stream = stream
+        # keep state
+        self.func = _locals['render']
+        self.source = source
+        self.symbols = symbols
         self.xmldoc = xmldoc
         self.parser = parser
         self.tree = tree
-        
+            
     def __reduce__(self):
         reconstructor, (cls, base, state), kwargs = \
                        GhostedByteCodeTemplate(self).__reduce__()
@@ -681,10 +684,6 @@
         return self.func(generation, *args, **kwargs)
 
     @property
-    def source(self):
-        return self.stream.getvalue()
-
-    @property
     def selectors(self):
         selectors = getattr(self, '_selectors', None)
         if selectors is not None:
@@ -704,26 +703,29 @@
     def __init__(self, template):
         self.code = marshal.dumps(template.func.func_code)
         self.defaults = len(template.func.func_defaults or ())
-        self.stream = template.stream
+        self.symbols = template.symbols
         self.xmldoc = template.xmldoc
         self.parser = template.parser
         
     @classmethod
     def rebuild(cls, state):
+        symbols = state['symbols']
+        xmldoc = state['xmldoc']
+        parser = state['parser']
+        tree, doctype = parser.parse(xmldoc)        
+
         _locals = {}
-        exec cls.suite.code in cls.suite._globals, _locals
+        _globals = symbols.copy()
+        _globals.update(cls.suite._globals)
+        exec cls.suite.code in _globals, _locals
+        
         func = _locals['render']
         func.func_defaults = ((None,)*state['defaults']) or None
         func.func_code = marshal.loads(state['code'])
 
-        stream = state['stream']
-        xmldoc = state['xmldoc']
-        parser = state['parser']
-        tree, doctype = parser.parse(xmldoc)
-        
         return dict(
             func=func,
-            stream=stream,
+            symbols=symbols,
             xmldoc=xmldoc,
             parser=parser,
             tree=tree)



More information about the Checkins mailing list