Author: Amaury Forgeot d'Arc <amaur...@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") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit