[pypy-svn] r61400 - in pypy/trunk/pypy/interpreter: astcompiler test

arigo at codespeak.net arigo at codespeak.net
Tue Jan 27 17:32:12 CET 2009


Author: arigo
Date: Tue Jan 27 17:32:11 2009
New Revision: 61400

Modified:
   pypy/trunk/pypy/interpreter/astcompiler/pycodegen.py
   pypy/trunk/pypy/interpreter/test/test_compiler.py
Log:
Set a correct co_firstlineno in the presence of decorators -- namely,
the line of the first decorator.


Modified: pypy/trunk/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/trunk/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/trunk/pypy/interpreter/astcompiler/pycodegen.py	Tue Jan 27 17:32:11 2009
@@ -298,9 +298,13 @@
             ndecorators = len(node.decorators.nodes)
         else:
             ndecorators = 0
+        if ndecorators > 0:
+            initialnode = node.decorators.nodes[0]
+        else:
+            initialnode = None
 
         gen = FunctionCodeGenerator(self.space, node, isLambda,
-                                    self.get_module())
+                                    self.get_module(), initialnode)
         node.code.accept( gen )
         gen.finish()
         self.set_lineno(node)
@@ -1347,7 +1351,7 @@
         self.emit('PRINT_EXPR')
         
 class AbstractFunctionCode(CodeGenerator):
-    def __init__(self, space, scope, func, isLambda, mod):
+    def __init__(self, space, scope, func, isLambda, mod, initialnode=None):
         assert scope is not None
         self.scope = scope
         self.localsfullyknown = self.scope.locals_fully_known()
@@ -1401,7 +1405,7 @@
             self.graph.setFlag(CO_VARKEYWORDS)
         if not graph.freevars and not graph.cellvars:
             self.graph.setFlag(CO_NOFREE)
-        self.set_lineno(func)
+        self.set_lineno(initialnode or func)
         self.generateArgUnpack(func.argnames)
 
     def get_module(self):
@@ -1438,9 +1442,9 @@
 
 class FunctionCodeGenerator(AbstractFunctionCode):
 
-    def __init__(self, space, func, isLambda, mod):
+    def __init__(self, space, func, isLambda, mod, initialnode=None):
         AbstractFunctionCode.__init__(self, space, func.scope,
-                                      func, isLambda, mod)
+                                      func, isLambda, mod, initialnode)
         if self.scope.generator:
             self.graph.setFlag(CO_GENERATOR)
             if self.scope.return_with_arg is not None:

Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py
==============================================================================
--- pypy/trunk/pypy/interpreter/test/test_compiler.py	(original)
+++ pypy/trunk/pypy/interpreter/test/test_compiler.py	Tue Jan 27 17:32:11 2009
@@ -376,6 +376,22 @@
         assert space.int_w(w_fline) == 2
         assert space.int_w(w_gline) == 6
 
+    def test_firstlineno_decorators(self):
+        snippet = str(py.code.Source(r'''
+            def foo(x): return x
+            @foo       # line 3
+            @foo       # line 4
+            def f():   # line 5
+                pass   # line 6
+            fline = f.func_code.co_firstlineno
+        '''))
+        code = self.compiler.compile(snippet, '<tmp>', 'exec', 0)
+        space = self.space
+        w_d = space.newdict()
+        code.exec_code(space, w_d, w_d)
+        w_fline = space.getitem(w_d, space.wrap('fline'))
+        assert space.int_w(w_fline) == 3
+
     def test_mangling(self):
         snippet = str(py.code.Source(r'''
             __g = "42"



More information about the Pypy-commit mailing list