[pypy-commit] pypy py3.6: The ast module now has a "Constant" node that AST optimizers can use.
amauryfa
pypy.commits at gmail.com
Sun Dec 10 16:35:28 EST 2017
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.6
Changeset: r93353:cadf41717a3f
Date: 2017-12-10 17:47 +0100
http://bitbucket.org/pypy/pypy/changeset/cadf41717a3f/
Log: The ast module now has a "Constant" node that AST optimizers can
use. Use it in place of PyPy's specific "Const".
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
@@ -1743,6 +1743,8 @@
return NameConstant.from_object(space, w_node)
if space.isinstance_w(w_node, get(space).w_Ellipsis):
return Ellipsis.from_object(space, w_node)
+ if space.isinstance_w(w_node, get(space).w_Constant):
+ return Constant.from_object(space, w_node)
if space.isinstance_w(w_node, get(space).w_Attribute):
return Attribute.from_object(space, w_node)
if space.isinstance_w(w_node, get(space).w_Subscript):
@@ -1755,8 +1757,6 @@
return List.from_object(space, w_node)
if space.isinstance_w(w_node, get(space).w_Tuple):
return Tuple.from_object(space, w_node)
- if space.isinstance_w(w_node, get(space).w_Const):
- return Const.from_object(space, w_node)
raise oefmt(space.w_TypeError,
"Expected expr node, got %T", w_node)
State.ast_type('expr', 'AST', None, ['lineno', 'col_offset'])
@@ -2841,6 +2841,43 @@
State.ast_type('Ellipsis', 'expr', [])
+class Constant(expr):
+
+ def __init__(self, value, lineno, col_offset):
+ self.value = value
+ expr.__init__(self, lineno, col_offset)
+
+ def walkabout(self, visitor):
+ visitor.visit_Constant(self)
+
+ def mutate_over(self, visitor):
+ return visitor.visit_Constant(self)
+
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Constant)
+ w_value = self.value # constant
+ space.setattr(w_node, space.newtext('value'), w_value)
+ w_lineno = space.newint(self.lineno) # int
+ space.setattr(w_node, space.newtext('lineno'), w_lineno)
+ w_col_offset = space.newint(self.col_offset) # int
+ space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
+ return w_node
+
+ @staticmethod
+ def from_object(space, w_node):
+ w_value = get_field(space, w_node, 'value', False)
+ w_lineno = get_field(space, w_node, 'lineno', False)
+ w_col_offset = get_field(space, w_node, 'col_offset', False)
+ _value = w_value
+ if _value is None:
+ raise_required_value(space, w_node, 'value')
+ _lineno = space.int_w(w_lineno)
+ _col_offset = space.int_w(w_col_offset)
+ return Constant(_value, _lineno, _col_offset)
+
+State.ast_type('Constant', 'expr', ['value'])
+
+
class Attribute(expr):
def __init__(self, value, attr, ctx, lineno, col_offset):
@@ -3137,43 +3174,6 @@
State.ast_type('Tuple', 'expr', ['elts', 'ctx'])
-class Const(expr):
-
- def __init__(self, obj, lineno, col_offset):
- self.obj = obj
- expr.__init__(self, lineno, col_offset)
-
- def walkabout(self, visitor):
- visitor.visit_Const(self)
-
- def mutate_over(self, visitor):
- return visitor.visit_Const(self)
-
- def to_object(self, space):
- w_node = space.call_function(get(space).w_Const)
- w_obj = self.obj # object
- space.setattr(w_node, space.newtext('obj'), w_obj)
- w_lineno = space.newint(self.lineno) # int
- space.setattr(w_node, space.newtext('lineno'), w_lineno)
- w_col_offset = space.newint(self.col_offset) # int
- space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
- return w_node
-
- @staticmethod
- def from_object(space, w_node):
- w_obj = get_field(space, w_node, 'obj', False)
- w_lineno = get_field(space, w_node, 'lineno', False)
- w_col_offset = get_field(space, w_node, 'col_offset', False)
- _obj = w_obj
- if _obj is None:
- raise_required_value(space, w_node, 'obj')
- _lineno = space.int_w(w_lineno)
- _col_offset = space.int_w(w_col_offset)
- return Const(_obj, _lineno, _col_offset)
-
-State.ast_type('Const', 'expr', ['obj'])
-
-
class expr_context(AST):
@staticmethod
def from_object(space, w_node):
@@ -4140,6 +4140,8 @@
return self.default_visitor(node)
def visit_Ellipsis(self, node):
return self.default_visitor(node)
+ def visit_Constant(self, node):
+ return self.default_visitor(node)
def visit_Attribute(self, node):
return self.default_visitor(node)
def visit_Subscript(self, node):
@@ -4152,8 +4154,6 @@
return self.default_visitor(node)
def visit_Tuple(self, node):
return self.default_visitor(node)
- def visit_Const(self, node):
- return self.default_visitor(node)
def visit_Slice(self, node):
return self.default_visitor(node)
def visit_ExtSlice(self, node):
@@ -4380,6 +4380,9 @@
def visit_Ellipsis(self, node):
pass
+ def visit_Constant(self, node):
+ pass
+
def visit_Attribute(self, node):
node.value.walkabout(self)
@@ -4399,9 +4402,6 @@
def visit_Tuple(self, node):
self.visit_sequence(node.elts)
- def visit_Const(self, node):
- pass
-
def visit_Slice(self, node):
if node.lower:
node.lower.walkabout(self)
diff --git a/pypy/interpreter/astcompiler/asthelpers.py b/pypy/interpreter/astcompiler/asthelpers.py
--- a/pypy/interpreter/astcompiler/asthelpers.py
+++ b/pypy/interpreter/astcompiler/asthelpers.py
@@ -128,7 +128,7 @@
_description = "dict comprehension"
-class __extend__(ast.Dict, ast.Set, ast.Str, ast.Bytes, ast.Num, ast.Const):
+class __extend__(ast.Dict, ast.Set, ast.Str, ast.Bytes, ast.Num, ast.Constant):
_description = "literal"
@@ -150,18 +150,18 @@
_description = "conditional expression"
-class __extend__(ast.Const):
+class __extend__(ast.Constant):
constant = True
def as_node_list(self, space):
try:
- values_w = space.unpackiterable(self.obj)
+ values_w = space.unpackiterable(self.value)
except OperationError:
return None
line = self.lineno
column = self.col_offset
- return [ast.Const(w_obj, line, column) for w_obj in values_w]
+ return [ast.Constant(w_obj, line, column) for w_obj in values_w]
class __extend__(ast.Str):
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
@@ -1039,9 +1039,9 @@
self.update_position(b.lineno)
self.load_const(b.s)
- def visit_Const(self, const):
+ def visit_Constant(self, const):
self.update_position(const.lineno)
- self.load_const(const.obj)
+ self.load_const(const.value)
def visit_Ellipsis(self, e):
self.load_const(self.space.w_Ellipsis)
diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -63,10 +63,10 @@
return True
-class __extend__(ast.Const):
+class __extend__(ast.Constant):
def as_constant(self):
- return self.obj
+ return self.value
class __extend__(ast.NameConstant):
@@ -208,7 +208,7 @@
else:
if self.space.int_w(w_len) > 20:
return binop
- return ast.Const(w_const, binop.lineno, binop.col_offset)
+ return ast.Constant(w_const, binop.lineno, binop.col_offset)
return binop
def visit_UnaryOp(self, unary):
@@ -229,7 +229,7 @@
except OperationError:
pass
else:
- return ast.Const(w_const, unary.lineno, unary.col_offset)
+ return ast.Constant(w_const, unary.lineno, unary.col_offset)
elif op == ast.Not:
compare = unary.operand
if isinstance(compare, ast.Compare) and len(compare.ops) == 1:
@@ -265,7 +265,7 @@
w_const = rep.value.as_constant()
if w_const is not None:
w_repr = self.space.repr(w_const)
- return ast.Const(w_repr, rep.lineno, rep.col_offset)
+ return ast.Constant(w_repr, rep.lineno, rep.col_offset)
return rep
def visit_Name(self, name):
@@ -282,7 +282,7 @@
elif iden == "False":
w_const = space.w_False
if w_const is not None:
- return ast.Const(w_const, name.lineno, name.col_offset)
+ return ast.NameConstant(w_const, name.lineno, name.col_offset)
return name
def visit_Tuple(self, tup):
@@ -303,7 +303,7 @@
else:
consts_w = []
w_consts = self.space.newtuple(consts_w)
- return ast.Const(w_consts, tup.lineno, tup.col_offset)
+ return ast.Constant(w_consts, tup.lineno, tup.col_offset)
def visit_Subscript(self, subs):
if subs.ctx == ast.Load:
@@ -340,6 +340,6 @@
# See test_const_fold_unicode_subscr
return subs
- return ast.Const(w_const, subs.lineno, subs.col_offset)
+ return ast.Constant(w_const, subs.lineno, subs.col_offset)
return subs
diff --git a/pypy/interpreter/astcompiler/tools/Python.asdl b/pypy/interpreter/astcompiler/tools/Python.asdl
--- a/pypy/interpreter/astcompiler/tools/Python.asdl
+++ b/pypy/interpreter/astcompiler/tools/Python.asdl
@@ -1,4 +1,8 @@
--- ASDL's six builtin types are identifier, int, string, bytes, object, singleton
+-- ASDL's 7 builtin types are:
+-- identifier, int, string, bytes, object, singleton, constant
+--
+-- singleton: None, True or False
+-- constant can be None, whereas None means "no value" for object.
module Python
{
@@ -75,6 +79,7 @@
| Bytes(bytes s)
| NameConstant(singleton value)
| Ellipsis
+ | Constant(constant value)
-- the following expression can appear in assignment context
| Attribute(expr value, identifier attr, expr_context ctx)
@@ -84,9 +89,6 @@
| List(expr* elts, expr_context ctx)
| Tuple(expr* elts, expr_context ctx)
- -- PyPy modification
- | Const(object obj)
-
-- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset)
diff --git a/pypy/interpreter/astcompiler/tools/asdl.py b/pypy/interpreter/astcompiler/tools/asdl.py
--- a/pypy/interpreter/astcompiler/tools/asdl.py
+++ b/pypy/interpreter/astcompiler/tools/asdl.py
@@ -34,7 +34,7 @@
# between the various node types.
builtin_types = {'identifier', 'string', 'bytes', 'int', 'bool', 'object',
- 'singleton'}
+ 'singleton', 'constant'}
class AST:
def __repr__(self):
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
@@ -130,7 +130,8 @@
def get_value_converter(self, field, value):
if field.type in self.data.simple_types:
return "%s_to_class[%s - 1]().to_object(space)" % (field.type, value)
- elif field.type in ("object", "singleton", "string", "bytes"):
+ elif field.type in ("object", "singleton", "constant",
+ "string", "bytes"):
return value
elif field.type == "bool":
return "space.newbool(%s)" % (value,)
@@ -155,7 +156,7 @@
def get_value_extractor(self, field, value):
if field.type in self.data.simple_types:
return "%s.from_object(space, %s)" % (field.type, value)
- elif field.type in ("object","singleton"):
+ elif field.type in ("object", "singleton", "constant"):
return value
elif field.type in ("string","bytes"):
return "check_string(space, %s)" % (value,)
diff --git a/pypy/interpreter/astcompiler/validate.py b/pypy/interpreter/astcompiler/validate.py
--- a/pypy/interpreter/astcompiler/validate.py
+++ b/pypy/interpreter/astcompiler/validate.py
@@ -318,6 +318,9 @@
def visit_Ellipsis(self, node):
pass
+ def visit_Constant(self, node):
+ pass
+
def visit_BoolOp(self, node):
if self._len(node.values) < 2:
raise ValidationError("BoolOp with less than 2 values")
More information about the pypy-commit
mailing list