[pypy-commit] pypy py3k-qualname: Failed attempt to update _make_function to add qualname to bytecode

Ian Foote noreply at buildbot.pypy.org
Sun Jul 27 12:24:21 CEST 2014


Author: Ian Foote <python at ian.feete.org>
Branch: py3k-qualname
Changeset: r72560:04e12b74c3cd
Date: 2014-07-26 17:22 +0200
http://bitbucket.org/pypy/pypy/changeset/04e12b74c3cd/

Log:	Failed attempt to update _make_function to add qualname to bytecode

diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -639,10 +639,10 @@
     return 1 - arg
 
 def _compute_MAKE_CLOSURE(arg):
-    return -1 - _num_args(arg) - ((arg >> 16) & 0xFFFF)
+    return -2 - _num_args(arg) - ((arg >> 16) & 0xFFFF)
 
 def _compute_MAKE_FUNCTION(arg):
-    return -_num_args(arg) - ((arg >> 16) & 0xFFFF)
+    return -1 -_num_args(arg) - ((arg >> 16) & 0xFFFF)
 
 def _compute_BUILD_SLICE(arg):
     if arg == 3:
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -282,9 +282,12 @@
         self.add_none_to_final_return = False
         mod.body.walkabout(self)
 
-    def _make_function(self, code, num_defaults=0):
+    def _make_function(self, code, num_defaults=0, w_qualname=None):
         """Emit the opcodes to turn a code object into a function."""
+        if w_qualname is None:
+            w_qualname = self.space.wrap(code.co_name.decode('utf-8'))
         code_index = self.add_const(code)
+        qualname_index = self.add_const(w_qualname)
         if code.co_freevars:
             # Load cell and free vars to pass on.
             for free in code.co_freevars:
@@ -296,9 +299,11 @@
                 self.emit_op_arg(ops.LOAD_CLOSURE, index)
             self.emit_op_arg(ops.BUILD_TUPLE, len(code.co_freevars))
             self.emit_op_arg(ops.LOAD_CONST, code_index)
+            self.emit_op_arg(ops.LOAD_CONST, qualname_index)
             self.emit_op_arg(ops.MAKE_CLOSURE, num_defaults)
         else:
             self.emit_op_arg(ops.LOAD_CONST, code_index)
+            self.emit_op_arg(ops.LOAD_CONST, qualname_index)
             self.emit_op_arg(ops.MAKE_FUNCTION, num_defaults)
 
     def _visit_kwonlydefaults(self, args):
@@ -597,7 +602,7 @@
             self.emit_op(ops.POP_TOP)
             if handler.name:
                 ## generate the equivalent of:
-                ## 
+                ##
                 ## try:
                 ##     # body
                 ## except type as name:
@@ -1084,7 +1089,7 @@
         self._make_call(0,
                         call.args, call.keywords,
                         call.starargs, call.kwargs)
-    
+
     def _call_has_no_star_args(self, call):
         return not call.starargs and not call.kwargs
 
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -35,7 +35,7 @@
 # different value for the highest 16 bits. Bump pypy_incremental_magic every
 # time you make pyc files incompatible
 
-pypy_incremental_magic = 48 # bump it by 16
+pypy_incremental_magic = 64 # bump it by 16
 assert pypy_incremental_magic % 16 == 0
 assert pypy_incremental_magic < 3000 # the magic number of Python 3. There are
                                      # no known magic numbers below this value
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1205,6 +1205,7 @@
     @jit.unroll_safe
     def _make_function(self, oparg, freevars=None):
         space = self.space
+        w_qualname = self.popvalue()
         w_codeobj = self.popvalue()
         codeobj = self.space.interp_w(PyCode, w_codeobj)
         if freevars is not None:
@@ -1236,7 +1237,7 @@
 
     @jit.unroll_safe
     def MAKE_CLOSURE(self, oparg, next_instr):
-        w_freevarstuple = self.peekvalue(1)
+        w_freevarstuple = self.peekvalue(2)
         freevars = [self.space.interp_w(Cell, cell)
                     for cell in self.space.fixedview(w_freevarstuple)]
         self._make_function(oparg, freevars)
diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py
--- a/pypy/interpreter/test/test_function.py
+++ b/pypy/interpreter/test/test_function.py
@@ -147,8 +147,11 @@
         """
 
     def test_qualname(self):
-        def f(): pass
+        def f():
+            pass
         assert hasattr(f, '__qualname__')
+        expected = 'AppTestFunctionIntrospection.test_qualname.<locals>.f'
+        assert f.__qualname__ == expected
 
 
 class AppTestFunction:
diff --git a/pypy/tool/importfun.py b/pypy/tool/importfun.py
--- a/pypy/tool/importfun.py
+++ b/pypy/tool/importfun.py
@@ -213,7 +213,7 @@
                     if postop != _op_.LOAD_ATTR:
                         break
                     seenloadattr = True
-                    
+
                 assert postop in storeops, 'postop'
 
                 storename = name_for_op(codeob, postop, postoparg)
@@ -561,10 +561,10 @@
         ourlink = link_for_name('', module, d)
         head = [html.title(module.name + '.' + d)]
         body = [html.h1([html.a(module.name, href=link_for_module(ourlink, module)), '.' + d])]
-        
+
         contents = []
 
-        for n in defuses[d]: 
+        for n in defuses[d]:
             N = module.system.modules[n]
             contents.append(html.li(html.a(n, href=link_for_module(ourlink, N))))
 


More information about the pypy-commit mailing list