[pypy-commit] pypy py3.3: Fix crash in ast module: check the presence of mandatory objects
amauryfa
noreply at buildbot.pypy.org
Thu Oct 9 23:05:56 CEST 2014
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.3
Changeset: r73871:73eefdc1c418
Date: 2014-10-09 21:52 +0200
http://bitbucket.org/pypy/pypy/changeset/73eefdc1c418/
Log: Fix crash in ast module: check the presence of mandatory objects
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
@@ -8,10 +8,9 @@
from pypy.interpreter.gateway import interp2app
-def raise_attriberr(space, w_obj, name):
- raise oefmt(space.w_AttributeError,
- "'%T' object has no attribute '%s'", w_obj, name)
-
+def raise_required_value(space, w_obj, name):
+ raise oefmt(space.w_ValueError,
+ "field %s is required for %T", name, w_obj)
def check_string(space, w_obj):
if not (space.isinstance_w(w_obj, space.w_str) or
@@ -261,6 +260,8 @@
def from_object(space, w_node):
w_body = get_field(space, w_node, 'body', False)
_body = expr.from_object(space, w_body)
+ if _body is None:
+ raise_required_value(space, w_node, 'body')
return Expression(_body)
State.ast_type('Expression', 'mod', ['body'])
@@ -416,7 +417,11 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_name = space.identifier_w(w_name)
+ if _name is None:
+ raise_required_value(space, w_node, 'name')
_args = arguments.from_object(space, w_args)
+ if _args is None:
+ raise_required_value(space, w_node, 'args')
body_w = space.unpackiterable(w_body)
_body = [stmt.from_object(space, w_item) for w_item in body_w]
decorator_list_w = space.unpackiterable(w_decorator_list)
@@ -509,6 +514,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_name = space.identifier_w(w_name)
+ if _name is None:
+ raise_required_value(space, w_node, 'name')
bases_w = space.unpackiterable(w_bases)
_bases = [expr.from_object(space, w_item) for w_item in bases_w]
keywords_w = space.unpackiterable(w_keywords)
@@ -646,6 +653,8 @@
targets_w = space.unpackiterable(w_targets)
_targets = [expr.from_object(space, w_item) for w_item in targets_w]
_value = expr.from_object(space, 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 Assign(_targets, _value, _lineno, _col_offset)
@@ -691,8 +700,14 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_target = expr.from_object(space, w_target)
+ if _target is None:
+ raise_required_value(space, w_node, 'target')
_op = operator.from_object(space, w_op)
+ if _op is None:
+ raise_required_value(space, w_node, 'op')
_value = expr.from_object(space, 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 AugAssign(_target, _op, _value, _lineno, _col_offset)
@@ -754,7 +769,11 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_target = expr.from_object(space, w_target)
+ if _target is None:
+ raise_required_value(space, w_node, 'target')
_iter = expr.from_object(space, w_iter)
+ if _iter is None:
+ raise_required_value(space, w_node, 'iter')
body_w = space.unpackiterable(w_body)
_body = [stmt.from_object(space, w_item) for w_item in body_w]
orelse_w = space.unpackiterable(w_orelse)
@@ -815,6 +834,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_test = expr.from_object(space, w_test)
+ if _test is None:
+ raise_required_value(space, w_node, 'test')
body_w = space.unpackiterable(w_body)
_body = [stmt.from_object(space, w_item) for w_item in body_w]
orelse_w = space.unpackiterable(w_orelse)
@@ -875,6 +896,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_test = expr.from_object(space, w_test)
+ if _test is None:
+ raise_required_value(space, w_node, 'test')
body_w = space.unpackiterable(w_body)
_body = [stmt.from_object(space, w_item) for w_item in body_w]
orelse_w = space.unpackiterable(w_orelse)
@@ -1139,6 +1162,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_test = expr.from_object(space, w_test)
+ if _test is None:
+ raise_required_value(space, w_node, 'test')
_msg = expr.from_object(space, w_msg) if w_msg is not None else None
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
@@ -1350,6 +1375,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_value = expr.from_object(space, 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 Expr(_value, _lineno, _col_offset)
@@ -1551,6 +1578,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_op = boolop.from_object(space, w_op)
+ if _op is None:
+ raise_required_value(space, w_node, 'op')
values_w = space.unpackiterable(w_values)
_values = [expr.from_object(space, w_item) for w_item in values_w]
_lineno = space.int_w(w_lineno)
@@ -1598,8 +1627,14 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_left = expr.from_object(space, w_left)
+ if _left is None:
+ raise_required_value(space, w_node, 'left')
_op = operator.from_object(space, w_op)
+ if _op is None:
+ raise_required_value(space, w_node, 'op')
_right = expr.from_object(space, w_right)
+ if _right is None:
+ raise_required_value(space, w_node, 'right')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return BinOp(_left, _op, _right, _lineno, _col_offset)
@@ -1640,7 +1675,11 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_op = unaryop.from_object(space, w_op)
+ if _op is None:
+ raise_required_value(space, w_node, 'op')
_operand = expr.from_object(space, w_operand)
+ if _operand is None:
+ raise_required_value(space, w_node, 'operand')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return UnaryOp(_op, _operand, _lineno, _col_offset)
@@ -1682,7 +1721,11 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_args = arguments.from_object(space, w_args)
+ if _args is None:
+ raise_required_value(space, w_node, 'args')
_body = expr.from_object(space, w_body)
+ if _body is None:
+ raise_required_value(space, w_node, 'body')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Lambda(_args, _body, _lineno, _col_offset)
@@ -1729,8 +1772,14 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_test = expr.from_object(space, w_test)
+ if _test is None:
+ raise_required_value(space, w_node, 'test')
_body = expr.from_object(space, w_body)
+ if _body is None:
+ raise_required_value(space, w_node, 'body')
_orelse = expr.from_object(space, w_orelse)
+ if _orelse is None:
+ raise_required_value(space, w_node, 'orelse')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return IfExp(_test, _body, _orelse, _lineno, _col_offset)
@@ -1873,6 +1922,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_elt = expr.from_object(space, w_elt)
+ if _elt is None:
+ raise_required_value(space, w_node, 'elt')
generators_w = space.unpackiterable(w_generators)
_generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
_lineno = space.int_w(w_lineno)
@@ -1921,6 +1972,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_elt = expr.from_object(space, w_elt)
+ if _elt is None:
+ raise_required_value(space, w_node, 'elt')
generators_w = space.unpackiterable(w_generators)
_generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
_lineno = space.int_w(w_lineno)
@@ -1974,7 +2027,11 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_key = expr.from_object(space, w_key)
+ if _key is None:
+ raise_required_value(space, w_node, 'key')
_value = expr.from_object(space, w_value)
+ if _value is None:
+ raise_required_value(space, w_node, 'value')
generators_w = space.unpackiterable(w_generators)
_generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
_lineno = space.int_w(w_lineno)
@@ -2023,6 +2080,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_elt = expr.from_object(space, w_elt)
+ if _elt is None:
+ raise_required_value(space, w_node, 'elt')
generators_w = space.unpackiterable(w_generators)
_generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
_lineno = space.int_w(w_lineno)
@@ -2098,6 +2157,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_value = expr.from_object(space, 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 YieldFrom(_value, _lineno, _col_offset)
@@ -2152,6 +2213,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_left = expr.from_object(space, w_left)
+ if _left is None:
+ raise_required_value(space, w_node, 'left')
ops_w = space.unpackiterable(w_ops)
_ops = [cmpop.from_object(space, w_item) for w_item in ops_w]
comparators_w = space.unpackiterable(w_comparators)
@@ -2224,6 +2287,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_func = expr.from_object(space, w_func)
+ if _func is None:
+ raise_required_value(space, w_node, 'func')
args_w = space.unpackiterable(w_args)
_args = [expr.from_object(space, w_item) for w_item in args_w]
keywords_w = space.unpackiterable(w_keywords)
@@ -2265,6 +2330,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_n = w_n
+ if _n is None:
+ raise_required_value(space, w_node, 'n')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Num(_n, _lineno, _col_offset)
@@ -2300,6 +2367,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_s = check_string(space, w_s)
+ if _s is None:
+ raise_required_value(space, w_node, 's')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Str(_s, _lineno, _col_offset)
@@ -2335,6 +2404,8 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_s = check_string(space, w_s)
+ if _s is None:
+ raise_required_value(space, w_node, 's')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Bytes(_s, _lineno, _col_offset)
@@ -2409,8 +2480,14 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_value = expr.from_object(space, w_value)
+ if _value is None:
+ raise_required_value(space, w_node, 'value')
_attr = space.identifier_w(w_attr)
+ if _attr is None:
+ raise_required_value(space, w_node, 'attr')
_ctx = expr_context.from_object(space, w_ctx)
+ if _ctx is None:
+ raise_required_value(space, w_node, 'ctx')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Attribute(_value, _attr, _ctx, _lineno, _col_offset)
@@ -2456,8 +2533,14 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_value = expr.from_object(space, w_value)
+ if _value is None:
+ raise_required_value(space, w_node, 'value')
_slice = slice.from_object(space, w_slice)
+ if _slice is None:
+ raise_required_value(space, w_node, 'slice')
_ctx = expr_context.from_object(space, w_ctx)
+ if _ctx is None:
+ raise_required_value(space, w_node, 'ctx')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Subscript(_value, _slice, _ctx, _lineno, _col_offset)
@@ -2498,7 +2581,11 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_value = expr.from_object(space, w_value)
+ if _value is None:
+ raise_required_value(space, w_node, 'value')
_ctx = expr_context.from_object(space, w_ctx)
+ if _ctx is None:
+ raise_required_value(space, w_node, 'ctx')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Starred(_value, _ctx, _lineno, _col_offset)
@@ -2538,7 +2625,11 @@
w_lineno = get_field(space, w_node, 'lineno', False)
w_col_offset = get_field(space, w_node, 'col_offset', False)
_id = space.identifier_w(w_id)
+ if _id is None:
+ raise_required_value(space, w_node, 'id')
_ctx = expr_context.from_object(space, w_ctx)
+ if _ctx is None:
+ raise_required_value(space, w_node, 'ctx')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Name(_id, _ctx, _lineno, _col_offset)
@@ -2586,6 +2677,8 @@
elts_w = space.unpackiterable(w_elts)
_elts = [expr.from_object(space, w_item) for w_item in elts_w]
_ctx = expr_context.from_object(space, w_ctx)
+ if _ctx is None:
+ raise_required_value(space, w_node, 'ctx')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return List(_elts, _ctx, _lineno, _col_offset)
@@ -2633,6 +2726,8 @@
elts_w = space.unpackiterable(w_elts)
_elts = [expr.from_object(space, w_item) for w_item in elts_w]
_ctx = expr_context.from_object(space, w_ctx)
+ if _ctx is None:
+ raise_required_value(space, w_node, 'ctx')
_lineno = space.int_w(w_lineno)
_col_offset = space.int_w(w_col_offset)
return Tuple(_elts, _ctx, _lineno, _col_offset)
@@ -2668,6 +2763,8 @@
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 Const(_value, _lineno, _col_offset)
@@ -2852,6 +2949,8 @@
def from_object(space, w_node):
w_value = get_field(space, w_node, 'value', False)
_value = expr.from_object(space, w_value)
+ if _value is None:
+ raise_required_value(space, w_node, 'value')
return Index(_value)
State.ast_type('Index', 'slice', ['value'])
@@ -3190,7 +3289,11 @@
w_iter = get_field(space, w_node, 'iter', False)
w_ifs = get_field(space, w_node, 'ifs', False)
_target = expr.from_object(space, w_target)
+ if _target is None:
+ raise_required_value(space, w_node, 'target')
_iter = expr.from_object(space, w_iter)
+ if _iter is None:
+ raise_required_value(space, w_node, 'iter')
ifs_w = space.unpackiterable(w_ifs)
_ifs = [expr.from_object(space, w_item) for w_item in ifs_w]
return comprehension(_target, _iter, _ifs)
@@ -3386,6 +3489,8 @@
w_arg = get_field(space, w_node, 'arg', False)
w_annotation = get_field(space, w_node, 'annotation', True)
_arg = space.identifier_w(w_arg)
+ if _arg is None:
+ raise_required_value(space, w_node, 'arg')
_annotation = expr.from_object(space, w_annotation) if w_annotation is not None else None
return arg(_arg, _annotation)
@@ -3417,7 +3522,11 @@
w_arg = get_field(space, w_node, 'arg', False)
w_value = get_field(space, w_node, 'value', False)
_arg = space.identifier_w(w_arg)
+ if _arg is None:
+ raise_required_value(space, w_node, 'arg')
_value = expr.from_object(space, w_value)
+ if _value is None:
+ raise_required_value(space, w_node, 'value')
return keyword(_arg, _value)
State.ast_type('keyword', 'AST', ['arg', 'value'])
@@ -3447,6 +3556,8 @@
w_name = get_field(space, w_node, 'name', False)
w_asname = get_field(space, w_node, 'asname', True)
_name = space.identifier_w(w_name)
+ if _name is None:
+ raise_required_value(space, w_node, 'name')
_asname = space.str_or_None_w(w_asname)
return alias(_name, _asname)
@@ -3480,6 +3591,8 @@
w_context_expr = get_field(space, w_node, 'context_expr', False)
w_optional_vars = get_field(space, w_node, 'optional_vars', True)
_context_expr = expr.from_object(space, w_context_expr)
+ if _context_expr is None:
+ raise_required_value(space, w_node, 'context_expr')
_optional_vars = expr.from_object(space, w_optional_vars) if w_optional_vars is not None else None
return withitem(_context_expr, _optional_vars)
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
@@ -189,6 +189,11 @@
else:
value = self.get_value_extractor(field, "w_%s" % (field.name,))
lines = ["_%s = %s" % (field.name, value)]
+ if not field.opt and field.type.value not in ("int",):
+ lines.append("if _%s is None:" % (field.name,))
+ lines.append(" raise_required_value(space, w_node, '%s')"
+ % (field.name,))
+
return lines
def make_converters(self, fields, name, extras=None):
@@ -408,10 +413,9 @@
from pypy.interpreter.gateway import interp2app
-def raise_attriberr(space, w_obj, name):
- raise oefmt(space.w_AttributeError,
- "'%T' object has no attribute '%s'", w_obj, name)
-
+def raise_required_value(space, w_obj, name):
+ raise oefmt(space.w_ValueError,
+ "field %s is required for %T", name, w_obj)
def check_string(space, w_obj):
if not (space.isinstance_w(w_obj, space.w_str) or
diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py
--- a/pypy/module/_ast/test/test_ast.py
+++ b/pypy/module/_ast/test/test_ast.py
@@ -441,3 +441,11 @@
str_node2 = copy.deepcopy(str_node)
dict_res = str_node2.__dict__
assert dict_res == {'n':2, 'lineno':2}
+
+ def test_empty_yield_from(self):
+ # Issue 16546: yield from value is not optional.
+ import ast
+ empty_yield_from = ast.parse("def f():\n yield from g()")
+ empty_yield_from.body[0].body[0].value.value = None
+ exc = raises(ValueError, compile, empty_yield_from, "<test>", "exec")
+ assert "field value is required" in str(exc.value)
More information about the pypy-commit
mailing list