Author: Amaury Forgeot d'Arc <amaur...@gmail.com> Branch: py3.3 Changeset: r75022:9ebba4eb7768 Date: 2014-12-18 22:36 +0100 http://bitbucket.org/pypy/pypy/changeset/9ebba4eb7768/
Log: Really implement __qualname__ for nested blocks. diff --git a/lib-python/3/importlib/_bootstrap.py b/lib-python/3/importlib/_bootstrap.py --- a/lib-python/3/importlib/_bootstrap.py +++ b/lib-python/3/importlib/_bootstrap.py @@ -405,8 +405,10 @@ due to the addition of new opcodes). """ -_RAW_MAGIC_NUMBER = 3230 | ord('\r') << 16 | ord('\n') << 24 -_MAGIC_BYTES = bytes(_RAW_MAGIC_NUMBER >> n & 0xff for n in range(0, 25, 8)) + +# PyPy change +import _imp +_MAGIC_BYTES = _imp.get_magic() _PYCACHE = '__pycache__' 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 @@ -157,6 +157,7 @@ def __init__(self, space, name, first_lineno, scope, compile_info): self.space = space self.name = name + self.qualname = name self.first_lineno = first_lineno self.compile_info = compile_info self.first_block = self.new_block() 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 @@ -205,7 +205,8 @@ """Convenience function for compiling a sub scope.""" generator = kind(self.space, name, node, lineno, self.symbols, self.compile_info) - return generator.assemble() + generator.qualname = '%s.%s' % (self.qualname, name) + return generator.assemble(), generator.qualname def push_frame_block(self, kind, block): self.frame_blocks.append((kind, block)) @@ -282,9 +283,11 @@ 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, qualname=None): """Emit the opcodes to turn a code object into a function.""" code_index = self.add_const(code) + w_qualname = self.space.wrap(qualname or code.co_name) + 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): @@ -359,9 +364,9 @@ oparg = num_defaults oparg |= kw_default_count << 8 oparg |= num_annotations << 16 - code = self.sub_scope(FunctionCodeGenerator, func.name, func, - func.lineno) - self._make_function(code, oparg) + code, qualname = self.sub_scope(FunctionCodeGenerator, func.name, func, + func.lineno) + self._make_function(code, oparg, qualname=qualname) # Apply decorators. if func.decorator_list: for i in range(len(func.decorator_list)): @@ -377,20 +382,22 @@ kw_default_count = self._visit_kwonlydefaults(args) self.visit_sequence(args.defaults) default_count = len(args.defaults) if args.defaults is not None else 0 - code = self.sub_scope(LambdaCodeGenerator, "<lambda>", lam, lam.lineno) + code, qualname = self.sub_scope( + LambdaCodeGenerator, "<lambda>", lam, lam.lineno) oparg = default_count oparg |= kw_default_count << 8 - self._make_function(code, oparg) + self._make_function(code, oparg, qualname=qualname) def visit_ClassDef(self, cls): self.update_position(cls.lineno, True) self.visit_sequence(cls.decorator_list) # 1. compile the class body into a code object - code = self.sub_scope(ClassCodeGenerator, cls.name, cls, cls.lineno) + code, qualname = self.sub_scope( + ClassCodeGenerator, cls.name, cls, cls.lineno) # 2. load the 'build_class' function self.emit_op(ops.LOAD_BUILD_CLASS) # 3. load a function (or closure) made from the code object - self._make_function(code, 0) + self._make_function(code, qualname=qualname) # 4. load class name self.load_const(self.space.wrap(cls.name.decode('utf-8'))) # 5. generate the rest of the code for the call @@ -1140,9 +1147,9 @@ self.use_next_block(anchor) def _compile_comprehension(self, node, name, sub_scope): - code = self.sub_scope(sub_scope, name, node, node.lineno) + code, qualname = self.sub_scope(sub_scope, name, node, node.lineno) self.update_position(node.lineno) - self._make_function(code) + self._make_function(code, qualname=qualname) first_comp = node.get_generators()[0] assert isinstance(first_comp, ast.comprehension) first_comp.iter.walkabout(self) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -36,10 +36,10 @@ 'w_kw_defs?'] def __init__(self, space, code, w_globals=None, defs_w=[], w_kw_defs=None, - closure=None, w_ann=None, forcename=None): + closure=None, w_ann=None, forcename=None, qualname=None): self.space = space self.name = forcename or code.co_name - self.qualname = self.name.decode('utf-8') # So far + self.qualname = qualname or self.name.decode('utf-8') self.w_doc = None # lazily read from code.getdocstring() self.code = code # Code instance self.w_func_globals = w_globals # the globals dictionary diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -36,7 +36,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 @@ -1215,6 +1215,8 @@ @jit.unroll_safe def _make_function(self, oparg, freevars=None): space = self.space + w_qualname = self.popvalue() + qualname = self.space.unicode_w(w_qualname) w_codeobj = self.popvalue() codeobj = self.space.interp_w(PyCode, w_codeobj) if freevars is not None: @@ -1238,7 +1240,7 @@ w_def = self.popvalue() space.setitem(w_kw_defs, w_def, w_name) fn = function.Function(space, codeobj, self.w_globals, defaultarguments, - w_kw_defs, freevars, w_ann) + w_kw_defs, freevars, w_ann, qualname=qualname) self.pushvalue(space.wrap(fn)) def MAKE_FUNCTION(self, oparg, next_instr): @@ -1246,7 +1248,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 @@ -23,7 +23,7 @@ def test_qualname(self): def f(): pass - assert f.__qualname__ == 'f' + assert f.__qualname__ == 'test_qualname.f' f.__qualname__ = 'qualname' assert f.__qualname__ == 'qualname' raises(TypeError, "f.__qualname__ = b'name'") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit