]> granicus.if.org Git - python/commitdiff
Patch #1638243: the compiler package is now able to correctly compile
authorGeorg Brandl <georg@python.org>
Sat, 27 Jan 2007 17:43:02 +0000 (17:43 +0000)
committerGeorg Brandl <georg@python.org>
Sat, 27 Jan 2007 17:43:02 +0000 (17:43 +0000)
a with statement; previously, executing code containing a with statement
compiled by the compiler package crashed the interpreter.

Lib/compiler/pycodegen.py
Lib/compiler/transformer.py
Lib/test/test_compiler.py
Misc/NEWS

index 8cf7d772daccd8d3e514c429b5276c98a314efec..b46b1c1489e25e8a5519db07fb3c49f84d238a05 100644 (file)
@@ -849,6 +849,8 @@ class CodeGenerator:
         self.emit('LOAD_CONST', None)
         self.nextBlock(final)
         self.setups.push((END_FINALLY, final))
+        self._implicitNameOp('LOAD', exitvar)
+        self._implicitNameOp('DELETE', exitvar)
         self.emit('WITH_CLEANUP')
         self.emit('END_FINALLY')
         self.setups.pop()
index a16dc553c4642631c30b9167afd06a2e345b2fd7..ac23ad18a99156b07bf74a318847a962f97336a0 100644 (file)
@@ -960,7 +960,7 @@ class Transformer:
         if nodelist[2][0] == token.COLON:
             var = None
         else:
-            var = self.com_node(nodelist[2])
+            var = self.com_assign(nodelist[2][2], OP_ASSIGN)
         return With(expr, var, body, lineno=nodelist[0][2])
 
     def com_with_var(self, nodelist):
index 81f2ea89250504071537814a719a1708d1920959..229d8a370fde6c05c937aa394709f7b3f256f4c6 100644 (file)
@@ -7,6 +7,12 @@ from random import random
 # How much time in seconds can pass before we print a 'Still working' message.
 _PRINT_WORKING_MSG_INTERVAL = 5 * 60
 
+class TrivialContext(object):
+    def __enter__(self):
+        return self
+    def __exit__(self, *exc_info):
+        pass
+
 class CompilerTest(unittest.TestCase):
 
     def testCompileLibrary(self):
@@ -123,6 +129,31 @@ class CompilerTest(unittest.TestCase):
                              'eval')
         self.assertEquals(eval(c), [(0, 3), (1, 3), (2, 3)])
 
+    def testWith(self):
+        # SF bug 1638243
+        c = compiler.compile('from __future__ import with_statement\n'
+                             'def f():\n'
+                             '    with TrivialContext():\n'
+                             '        return 1\n'
+                             'result = f()',
+                             '<string>',
+                             'exec' )
+        dct = {'TrivialContext': TrivialContext}
+        exec c in dct
+        self.assertEquals(dct.get('result'), 1)
+
+    def testWithAss(self):
+        c = compiler.compile('from __future__ import with_statement\n'
+                             'def f():\n'
+                             '    with TrivialContext() as tc:\n'
+                             '        return 1\n'
+                             'result = f()',
+                             '<string>',
+                             'exec' )
+        dct = {'TrivialContext': TrivialContext}
+        exec c in dct
+        self.assertEquals(dct.get('result'), 1)
+
 
 NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard)
 
index 8bbae96d320d700ea833ed8dcc499bfe8c572766..82c3d64a890cd46b4ac334a37b58ef9647a1cf0c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -123,6 +123,10 @@ Core and builtins
 Library
 -------
 
+- Patch #1638243: the compiler package is now able to correctly compile
+  a with statement; previously, executing code containing a with statement
+  compiled by the compiler package crashed the interpreter.
+
 - Bug #1643943: Fix time.strptime's support for the %U directive.
 
 - Patch #1643874: memory leak in ctypes fixed.