diff options
author | Marius Gedminas <marius@gedmin.as> | 2006-08-25 17:05:12 +0000 |
---|---|---|
committer | Marius Gedminas <marius@gedmin.as> | 2006-08-25 17:05:12 +0000 |
commit | 925879cef759010ff13fe575849cbabca3dcdacb (patch) | |
tree | 062ac63d263da7edc594a6d0584d2f5980b407ed | |
parent | 828aa4ad474f1c4c4e18517ca9919c4a15c25caf (diff) | |
download | zope-tal-925879cef759010ff13fe575849cbabca3dcdacb.tar.gz |
Fixed issue 697: wrong page template referenced in the traceback if an
exception occurs inside fill-slot.
Note that it is OK to remove that code in do_defineSlot, because it is
redundant: TALGenerator emits a setSourceFile opcode to restore the
source file after emitting a defineSlot opcode.
Thanks to Fred Drake for sanity checking.
-rw-r--r-- | talinterpreter.py | 4 | ||||
-rw-r--r-- | tests/test_talinterpreter.py | 58 |
2 files changed, 56 insertions, 6 deletions
diff --git a/talinterpreter.py b/talinterpreter.py index 5e34e97..9c801bf 100644 --- a/talinterpreter.py +++ b/talinterpreter.py @@ -945,13 +945,9 @@ class TALInterpreter(object): # render the slot filler. chopped = macs[i:] del macs[i:] - prev_source = self.sourceFile try: self.interpret(slot) finally: - if self.sourceFile != prev_source: - self.engine.setSourceFile(prev_source) - self.sourceFile = prev_source # Restore the stack entries. for mac in chopped: mac.entering = False # Not entering diff --git a/tests/test_talinterpreter.py b/tests/test_talinterpreter.py index 651c0d7..c9e8ed7 100644 --- a/tests/test_talinterpreter.py +++ b/tests/test_talinterpreter.py @@ -23,9 +23,11 @@ import unittest from StringIO import StringIO from zope.tal.taldefs import METALError, I18NError, TAL_VERSION +from zope.tal.taldefs import TALExpressionError from zope.tal.htmltalparser import HTMLTALParser from zope.tal.talparser import TALParser from zope.tal.talinterpreter import TALInterpreter +from zope.tal.talgenerator import TALGenerator from zope.tal.dummyengine import DummyEngine from zope.tal.dummyengine import MultipleDomainsDummyEngine from zope.tal.dummyengine import DummyTranslationDomain @@ -35,8 +37,9 @@ from zope.i18nmessageid import Message class TestCaseBase(unittest.TestCase): - def _compile(self, source): - parser = HTMLTALParser() + def _compile(self, source, source_file=None): + generator = TALGenerator(xml=0, source_file=source_file) + parser = HTMLTALParser(generator) parser.parseString(source) program, macros = parser.getCode() return program, macros @@ -777,6 +780,56 @@ class TestSourceAnnotations(unittest.TestCase): self.assert_(interpreter._pending_source_annotation) +class TestErrorTracebacks(TestCaseBase): + + # Regression test for http://www.zope.org/Collectors/Zope3-dev/697 + + def test_define_slot_does_not_clobber_source_file_on_exception(self): + m_program, m_macros = self._compile(""" + <div metal:define-macro="amacro"> + <div metal:define-slot="aslot"> + </div> + </div> + """, source_file='macros.pt') + p_program, p_macros = self._compile(""" + <div metal:use-macro="amacro"> + <div metal:fill-slot="aslot"> + <tal:x replace="no_such_thing" /> + </div> + </div> + """, source_file='page.pt') + engine = DummyEngine(macros=m_macros) + interp = TALInterpreter(p_program, {}, engine, StringIO()) + # Expect TALExpressionError: unknown variable: 'no_such_thing' + self.assertRaises(TALExpressionError, interp) + # Now the engine should know where the error occurred + self.assertEquals(engine.source_file, 'page.pt') + self.assertEquals(engine.position, (4, 16)) + + def test_define_slot_restores_source_file_if_no_exception(self): + m_program, m_macros = self._compile(""" + <div metal:define-macro="amacro"> + <div metal:define-slot="aslot"> + </div> + <tal:x replace="no_such_thing" /> + </div> + """, source_file='macros.pt') + p_program, p_macros = self._compile(""" + <div metal:use-macro="amacro"> + <div metal:fill-slot="aslot"> + </div> + </div> + """, source_file='page.pt') + engine = DummyEngine(macros=m_macros) + interp = TALInterpreter(p_program, {}, engine, StringIO()) + # Expect TALExpressionError: unknown variable: 'no_such_thing' + self.assertRaises(TALExpressionError, interp) + # Now the engine should know where the error occurred + self.assertEquals(engine.source_file, 'macros.pt') + self.assertEquals(engine.position, (5, 14)) + + + def test_suite(): suite = unittest.makeSuite(I18NErrorsTestCase) suite.addTest(unittest.makeSuite(MacroErrorsTestCase)) @@ -786,6 +839,7 @@ def test_suite(): suite.addTest(unittest.makeSuite(I18NCornerTestCaseMessage)) suite.addTest(unittest.makeSuite(UnusedExplicitDomainTestCase)) suite.addTest(unittest.makeSuite(TestSourceAnnotations)) + suite.addTest(unittest.makeSuite(TestErrorTracebacks)) # TODO: Deactivated test, since we have not found a solution for this and # it is a deep and undocumented HTML parser issue. |