[pypy-svn] r16493 - in pypy/dist/pypy/interpreter: stablecompiler test

hpk at codespeak.net hpk at codespeak.net
Thu Aug 25 15:44:55 CEST 2005


Author: hpk
Date: Thu Aug 25 15:44:54 2005
New Revision: 16493

Modified:
   pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py
   pypy/dist/pypy/interpreter/stablecompiler/symbols.py
   pypy/dist/pypy/interpreter/test/test_compiler.py
Log:
(hpk, pedronis) 

make a few more scope-related problems vanish
(see added tests).  Next is to try to tackle 
the last remaining problems of test_scope.py. 



Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py	(original)
+++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py	Thu Aug 25 15:44:54 2005
@@ -266,6 +266,11 @@
         self._nameOp('STORE', name)
 
     def loadName(self, name):
+        if (self.scope.nested and not self.scope.localsfullyknown and
+            name in self.scope.hasbeenfree):
+            raise SyntaxError("cannot reference variable '%s' because "
+                              "of ambiguity between "
+                              "scopes" % name)
         self._nameOp('LOAD', name)
 
     def delName(self, name):

Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py
==============================================================================
--- pypy/dist/pypy/interpreter/stablecompiler/symbols.py	(original)
+++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py	Thu Aug 25 15:44:54 2005
@@ -22,6 +22,7 @@
         self.globals = {}
         self.params = {}
         self.frees = {}
+        self.hasbeenfree = {}
         self.cells = {}
         self.children = []
         # nested is true if the class could contain free variables,
@@ -113,6 +114,7 @@
             if not (self.defs.has_key(name) or
                     self.globals.has_key(name)):
                 free[name] = 1
+        self.hasbeenfree.update(free)
         return free.keys()
 
     def handle_children(self):

Modified: pypy/dist/pypy/interpreter/test/test_compiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_compiler.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_compiler.py	Thu Aug 25 15:44:54 2005
@@ -3,6 +3,7 @@
 import py
 from pypy.interpreter.pycompiler import CPythonCompiler, PythonCompiler
 from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.error import OperationError
 
 
 class BaseTestCompiler:
@@ -64,6 +65,57 @@
         w_a = space.getitem(w_globals, space.wrap('a'))
         assert space.int_w(w_a) == 1
 
+    def test_scope_unoptimized_clash1(self):
+        # mostly taken from test_scope.py 
+        e = py.test.raises(OperationError, self.compiler.compile, """if 1:
+            def unoptimized_clash1(strip):
+                def f(s):
+                    from string import *
+                    return strip(s) # ambiguity: free or local
+                return f""", '', 'exec', 0)
+        ex = e.value 
+        assert ex.match(self.space, self.space.w_SyntaxError)
+
+    def test_scope_unoptimized_clash1_b(self):
+        # mostly taken from test_scope.py 
+        e = py.test.raises(OperationError, self.compiler.compile, """if 1:
+            def unoptimized_clash1(strip):
+                def f():
+                    from string import *
+                    return s # ambiguity: free or local
+                return f""", '', 'exec', 0)
+        ex = e.value 
+        assert ex.match(self.space, self.space.w_SyntaxError)
+
+    def test_scope_exec_in_nested(self):
+        e = py.test.raises(OperationError, self.compiler.compile, """if 1:
+            def unoptimized_clash1(x):
+                def f():
+                    exec "z=3"
+                    return x
+                return f""", '', 'exec', 0)
+        ex = e.value 
+        assert ex.match(self.space, self.space.w_SyntaxError)
+
+    def test_scope_importstar_in_nested(self):
+        e = py.test.raises(OperationError, self.compiler.compile, """if 1:
+            def unoptimized_clash1(x):
+                def f():
+                    from string import * 
+                    return x
+                return f""", '', 'exec', 0)
+        ex = e.value 
+        assert ex.match(self.space, self.space.w_SyntaxError)
+
+    def XXXtest_scope_importstar_with_nested_free(self):
+        e = py.test.raises(OperationError, self.compiler.compile, """if 1:
+            def clash(x):
+                from string import *
+                def f(s):
+                    return strip(s)
+                return f""", '', 'exec', 0)
+        ex = e.value 
+        assert ex.match(self.space, self.space.w_SyntaxError)
 
 class TestECCompiler(BaseTestCompiler):
     def setup_method(self, method):



More information about the Pypy-commit mailing list