[pypy-svn] r18781 - in pypy/dist/pypy/interpreter: astcompiler test

arigo at codespeak.net arigo at codespeak.net
Thu Oct 20 00:23:02 CEST 2005


Author: arigo
Date: Thu Oct 20 00:23:01 2005
New Revision: 18781

Modified:
   pypy/dist/pypy/interpreter/astcompiler/pyassem.py
   pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
   pypy/dist/pypy/interpreter/astcompiler/symbols.py
   pypy/dist/pypy/interpreter/test/test_compiler.py
Log:
More compiler bugs!  Cool!

Blah blah name mangling blah.

Yes I know I should not write check-in messages after midnight.


Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pyassem.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py	Thu Oct 20 00:23:01 2005
@@ -434,8 +434,8 @@
 
 class PyFlowGraph(FlowGraph):
 
-    def __init__(self, space, name, filename, args=None, optimized=0,
-                 klass=0, newlocals=0):
+    def __init__(self, space, name, filename, args=None, mangler=None,
+                 optimized=0, klass=0, newlocals=0):
         FlowGraph.__init__(self, space)
         if args is None:
             args = []
@@ -465,7 +465,7 @@
         for i in range(len(args)):
             var = args[i]
             if isinstance(var, ast.AssName):
-                self.varnames.append(var.name )
+                self.varnames.append(mangler.mangle(var.name))
             elif isinstance(var, ast.AssTuple):
                 self.varnames.append('.%d' % (2 * i))
         self.stage = RAW

Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	Thu Oct 20 00:23:01 2005
@@ -146,6 +146,7 @@
     """
 
     scopeambiguity = False
+    class_name = ""
 
     def __init__(self, space, graph):
         self.space = space
@@ -155,7 +156,6 @@
         self.genexpr_cont_stack = []
         self.graph = graph
         self.optimized = 0 # is namespace access optimized?
-        self.class_name = "" # provide default for instance variable
 
         # XXX set flags based on future features
         futures = self.get_module().futures
@@ -236,7 +236,7 @@
     def delName(self, name, lineno):
         if name in ('None', '__debug__'):
             raise SyntaxError('deleting %s is not allowed' % name, lineno)
-        scope = self.scope.check_name(name)
+        scope = self.scope.check_name(self.mangle(name))
         if scope == SC_CELL:
             raise SyntaxError("can not delete variable '%s' "
                               "referenced in nested scope" % name, lineno)
@@ -1238,6 +1238,7 @@
         
 class AbstractFunctionCode(CodeGenerator):
     def __init__(self, space, func, isLambda, class_name, mod):
+        self.class_name = class_name
         self.module = mod
         if isLambda:
             name = "<lambda>"
@@ -1248,11 +1249,13 @@
         argnames = {}
         for arg in func.argnames:
             if isinstance(arg, ast.AssName):
-                if arg.name in argnames:
-                    raise SyntaxError("duplicate argument '%s' in function definition" % arg.name, func.lineno)
-                argnames[arg.name] = 1
+                argname = self.mangle(arg.name)
+                if argname in argnames:
+                    raise SyntaxError("duplicate argument '%s' in function definition" % argname, func.lineno)
+                argnames[argname] = 1
             elif isinstance(arg, ast.AssTuple):
                 for argname in arg.getArgNames():
+                    argname = self.mangle(argname)
                     if argname in argnames:
                         raise SyntaxError("duplicate argument '%s' in function definition" % argname, func.lineno)
                     argnames[argname] = 1
@@ -1260,11 +1263,11 @@
             raise SyntaxError('assignment to None is not allowed', func.lineno)
 
         graph = pyassem.PyFlowGraph(space, name, func.filename, func.argnames,
+                                    mangler=self,
                                     optimized=self.localsfullyknown,
                                     newlocals=1)
         self.isLambda = isLambda
         CodeGenerator.__init__(self, space, graph)
-        self.class_name = class_name
         self.optimized = 1
 
         if not isLambda and not space.is_w(func.doc, space.w_None):

Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/symbols.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/symbols.py	Thu Oct 20 00:23:01 2005
@@ -157,6 +157,7 @@
         """
         child_globals = []
         for name in names:
+            name = self.mangle(name)
             sc = self.check_name(name)
             if self.nested:
                 if sc == SC_UNKNOWN or sc == SC_FREE \
@@ -416,6 +417,7 @@
     def visitGlobal(self, node ):
         scope = self.cur_scope()
         for name in node.names:
+            name = scope.mangle(name)
             namescope = scope.check_name(name)
             if namescope == SC_LOCAL:
                 issue_warning(self.space, "name '%s' is assigned to before "

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 Oct 20 00:23:01 2005
@@ -338,6 +338,36 @@
         assert space.int_w(w_fline) == 2
         assert space.int_w(w_gline) == 6
 
+    def test_mangling(self):
+        snippet = str(py.code.Source(r'''
+            __g = "42"
+            class X:
+                def __init__(self, u):
+                    self.__u = u
+                def __f(__self, __n):
+                    global __g
+                    __NameError = NameError
+                    try:
+                        yield "found: " + __g
+                    except __NameError, __e:
+                        yield "not found: " + str(__e)
+                    del __NameError
+                    for __i in range(__self.__u * __n):
+                        yield locals()
+            result = X(2)
+            assert not hasattr(result, "__f")
+            result = list(result._X__f(3))
+            assert len(result) == 7
+            assert result[0].startswith("not found: ")
+            for d in result[1:]:
+                for key, value in d.items():
+                    assert not key.startswith('__')
+        '''))
+        code = self.compiler.compile(snippet, '<tmp>', 'exec', 0)
+        space = self.space
+        w_d = space.newdict([])
+        space.exec_(code, w_d, w_d)
+
 class TestECCompiler(BaseTestCompiler):
     def setup_method(self, method):
         self.compiler = self.space.getexecutioncontext().compiler



More information about the Pypy-commit mailing list