[pypy-commit] pypy py3.5: Python.asdl gives attributes (lineno, col_offset) to the class 'arg',

arigo pypy.commits at gmail.com
Tue Jan 24 12:11:15 EST 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r89751:fe93a6ca25bb
Date: 2017-01-24 18:10 +0100
http://bitbucket.org/pypy/pypy/changeset/fe93a6ca25bb/

Log:	Python.asdl gives attributes (lineno, col_offset) to the class
	'arg', but because this ended up as a Product instead of a Sum the
	attributes were ignored. Fix

diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -3879,9 +3879,11 @@
 
 class arg(AST):
 
-    def __init__(self, arg, annotation):
+    def __init__(self, arg, annotation, lineno, col_offset):
         self.arg = arg
         self.annotation = annotation
+        self.lineno = lineno
+        self.col_offset = col_offset
 
     def mutate_over(self, visitor):
         if self.annotation:
@@ -3897,19 +3899,27 @@
         space.setattr(w_node, space.wrap('arg'), w_arg)
         w_annotation = self.annotation.to_object(space) if self.annotation is not None else space.w_None  # expr
         space.setattr(w_node, space.wrap('annotation'), w_annotation)
+        w_lineno = space.wrap(self.lineno)  # int
+        space.setattr(w_node, space.wrap('lineno'), w_lineno)
+        w_col_offset = space.wrap(self.col_offset)  # int
+        space.setattr(w_node, space.wrap('col_offset'), w_col_offset)
         return w_node
 
     @staticmethod
     def from_object(space, w_node):
         w_arg = get_field(space, w_node, 'arg', False)
         w_annotation = get_field(space, w_node, 'annotation', True)
+        w_lineno = get_field(space, w_node, 'lineno', False)
+        w_col_offset = get_field(space, w_node, 'col_offset', False)
         _arg = space.identifier_w(w_arg)
         if _arg is None:
             raise_required_value(space, w_node, 'arg')
         _annotation = expr.from_object(space, w_annotation)
-        return arg(_arg, _annotation)
-
-State.ast_type('arg', 'AST', ['arg', 'annotation'])
+        _lineno = space.int_w(w_lineno)
+        _col_offset = space.int_w(w_col_offset)
+        return arg(_arg, _annotation, _lineno, _col_offset)
+
+State.ast_type('arg', 'AST', ['arg', 'annotation'], ['lineno', 'col_offset'])
 
 class keyword(AST):
 
diff --git a/pypy/interpreter/astcompiler/astbuilder.py b/pypy/interpreter/astcompiler/astbuilder.py
--- a/pypy/interpreter/astcompiler/astbuilder.py
+++ b/pypy/interpreter/astcompiler/astbuilder.py
@@ -665,7 +665,8 @@
                 argname = name_node.get_value()
                 argname = self.new_identifier(argname)
                 self.check_forbidden_name(argname, name_node)
-                kwonly.append(ast.arg(argname, ann))
+                kwonly.append(ast.arg(argname, ann, arg.get_lineno(),
+                                                    arg.get_column()))
                 i += 2
             elif arg_type == tokens.DOUBLESTAR:
                 return i
@@ -678,7 +679,7 @@
         ann = None
         if arg_node.num_children() == 3:
             ann = self.handle_expr(arg_node.get_child(2))
-        return ast.arg(name, ann)
+        return ast.arg(name, ann, arg_node.get_lineno(), arg_node.get_column())
 
     def handle_stmt(self, stmt):
         stmt_type = stmt.type
diff --git a/pypy/interpreter/astcompiler/test/test_validate.py b/pypy/interpreter/astcompiler/test/test_validate.py
--- a/pypy/interpreter/astcompiler/test/test_validate.py
+++ b/pypy/interpreter/astcompiler/test/test_validate.py
@@ -51,18 +51,18 @@
             args = ast.arguments(args, vararg, kwonlyargs,
                                  kw_defaults, kwarg, defaults)
             return fac(args)
-        args = [ast.arg("x", ast.Name("x", ast.Store, 0, 0))]
+        args = [ast.arg("x", ast.Name("x", ast.Store, 0, 0), 0, 0)]
         check(arguments(args=args), "must have Load context")
         check(arguments(kwonlyargs=args), "must have Load context")
         check(arguments(defaults=[ast.Num(self.space.wrap(3), 0, 0)]),
                        "more positional defaults than args")
         check(arguments(kw_defaults=[ast.Num(self.space.wrap(4), 0, 0)]),
                        "length of kwonlyargs is not the same as kw_defaults")
-        args = [ast.arg("x", ast.Name("x", ast.Load, 0, 0))]
+        args = [ast.arg("x", ast.Name("x", ast.Load, 0, 0), 0, 0)]
         check(arguments(args=args, defaults=[ast.Name("x", ast.Store, 0, 0)]),
                        "must have Load context")
-        args = [ast.arg("a", ast.Name("x", ast.Load, 0, 0)),
-                ast.arg("b", ast.Name("y", ast.Load, 0, 0))]
+        args = [ast.arg("a", ast.Name("x", ast.Load, 0, 0), 0, 0),
+                ast.arg("b", ast.Name("y", ast.Load, 0, 0), 0, 0)]
         check(arguments(kwonlyargs=args,
                           kw_defaults=[None, ast.Name("x", ast.Store, 0, 0)]),
                           "must have Load context")
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -56,6 +56,7 @@
 
     def visitSum(self, sum, base):
         if is_simple_sum(sum):
+            assert not sum.attributes
             self.emit("class %s(AST):" % (base,))
             self.emit("@staticmethod", 1)
             self.emit("def from_object(space, w_node):", 1)
@@ -111,15 +112,19 @@
     def visitProduct(self, product, name):
         self.emit("class %s(AST):" % (name,))
         self.emit("")
-        self.make_constructor(product.fields, product)
+        self.make_constructor(product.fields + product.attributes, product)
         self.emit("")
         self.make_mutate_over(product, name)
         self.emit("def walkabout(self, visitor):", 1)
         self.emit("visitor.visit_%s(self)" % (name,), 2)
         self.emit("")
-        self.make_converters(product.fields, name)
-        self.emit("State.ast_type(%r, 'AST', %s)" %
-                  (name, [f.name for f in product.fields]))
+        self.make_converters(product.fields + product.attributes, name)
+        if product.attributes:
+            attr_names = ', %s' % ([a.name for a in product.attributes],)
+        else:
+            attr_names = ''
+        self.emit("State.ast_type(%r, 'AST', %s%s)" %
+                  (name, [f.name for f in product.fields], attr_names))
         self.emit("")
 
     def get_value_converter(self, field, value):


More information about the pypy-commit mailing list