[ZPT] CVS: Zope3/lib/python/Zope/TAL - DummyEngine.py:1.28.14.4 TALGenerator.py:1.52.16.4 TALInterpreter.py:1.63.10.4

Shane Hathaway shane@cvs.zope.org
Fri, 22 Mar 2002 15:34:13 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/TAL
In directory cvs.zope.org:/tmp/cvs-serv30491

Modified Files:
      Tag: Zope-3x-branch
	DummyEngine.py TALGenerator.py TALInterpreter.py 
Log Message:
Added a test of source file tracking in TAL and fixed the bugs the test
revealed. Also made sure tal:on-error can catch string exceptions in addition
to class exceptions.


=== Zope3/lib/python/Zope/TAL/DummyEngine.py 1.28.14.3 => 1.28.14.4 ===
             except:
                 raise TALESError("evaluation error in %s" % `expr`)
+        if type == "position":
+            # Insert the current source file name, line number,
+            # and column offset.
+            if self.position:
+                lineno, offset = self.position
+            else:
+                lineno, offset = None, None
+            return '%s (%s,%s)' % (self.source_file, lineno, offset)
         raise TALESError("unrecognized expression: " + `expression`)
 
     def evaluateValue(self, expr):


=== Zope3/lib/python/Zope/TAL/TALGenerator.py 1.52.16.3 => 1.52.16.4 ===
             if fillSlot:
                 self.pushProgram()
+                if self.source_file is not None:
+                    self.emit("setSourceFile", self.source_file)
                 todo["fillSlot"] = fillSlot
                 self.inMacroUse = 0
         else:


=== Zope3/lib/python/Zope/TAL/TALInterpreter.py 1.63.10.3 => 1.63.10.4 ===
         self.level = 0
         self.scopeLevel = 0
+        self.sourceFile = None
 
     def saveState(self):
         return (self.position, self.col, self.stream,
@@ -202,6 +203,7 @@
     bytecode_handlers["mode"] = do_mode
 
     def do_setSourceFile(self, source_file):
+        self.sourceFile = source_file
         self.engine.setSourceFile(source_file)
     bytecode_handlers["setSourceFile"] = do_setSourceFile
 
@@ -519,7 +521,11 @@
                 raise METALError("macro %s has incompatible mode %s" %
                                  (`macroName`, `mode`), self.position)
         self.pushMacro(macroName, compiledSlots)
+        prev_source = self.sourceFile
         self.interpret(macro)
+        if self.sourceFile != prev_source:
+            self.engine.setSourceFile(prev_source)
+            self.sourceFile = prev_source
         self.popMacro()
     bytecode_handlers["useMacro"] = do_useMacro
 
@@ -538,7 +544,11 @@
             macroName, slots = self.popMacro()[:2]
             slot = slots.get(slotName)
             if slot is not None:
+                prev_source = self.sourceFile
                 self.interpret(slot)
+                if self.sourceFile != prev_source:
+                    self.engine.setSourceFile(prev_source)
+                    self.sourceFile = prev_source
                 self.pushMacro(macroName, slots, entering=0)
                 return
             self.pushMacro(macroName, slots)
@@ -557,7 +567,8 @@
         self._stream_write = stream.write
         try:
             self.interpret(block)
-        except Exception, exc:
+        except:
+            exc = sys.exc_info()[1]
             self.restoreState(state)
             engine = self.engine
             engine.beginScope()