Issue #16546: make ast.YieldFrom argument mandatory.
This commit is contained in:
parent
9982c53c2f
commit
ded35aeb9d
|
@ -399,6 +399,14 @@ class AST_Tests(unittest.TestCase):
|
||||||
compile(m, "<test>", "exec")
|
compile(m, "<test>", "exec")
|
||||||
self.assertIn("string must be of type str", str(cm.exception))
|
self.assertIn("string must be of type str", str(cm.exception))
|
||||||
|
|
||||||
|
def test_empty_yield_from(self):
|
||||||
|
# Issue 16546: yield from value is not optional.
|
||||||
|
empty_yield_from = ast.parse("def f():\n yield from g()")
|
||||||
|
empty_yield_from.body[0].body[0].value.value = None
|
||||||
|
with self.assertRaises(ValueError) as cm:
|
||||||
|
compile(empty_yield_from, "<test>", "exec")
|
||||||
|
self.assertIn("field value is required", str(cm.exception))
|
||||||
|
|
||||||
|
|
||||||
class ASTHelpers_Test(unittest.TestCase):
|
class ASTHelpers_Test(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ What's New in Python 3.3.1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #16546: Fix: ast.YieldFrom argument is now mandatory.
|
||||||
|
|
||||||
- Issue #16514: Fix regression causing a traceback when sys.path[0] is None
|
- Issue #16514: Fix regression causing a traceback when sys.path[0] is None
|
||||||
(actually, any non-string or non-bytes type).
|
(actually, any non-string or non-bytes type).
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ module Python
|
||||||
| GeneratorExp(expr elt, comprehension* generators)
|
| GeneratorExp(expr elt, comprehension* generators)
|
||||||
-- the grammar constrains where yield expressions can occur
|
-- the grammar constrains where yield expressions can occur
|
||||||
| Yield(expr? value)
|
| Yield(expr? value)
|
||||||
| YieldFrom(expr? value)
|
| YieldFrom(expr value)
|
||||||
-- need sequences for compare to distinguish between
|
-- need sequences for compare to distinguish between
|
||||||
-- x < 4 < 3 and (x < 4) < 3
|
-- x < 4 < 3 and (x < 4) < 3
|
||||||
| Compare(expr left, cmpop* ops, expr* comparators)
|
| Compare(expr left, cmpop* ops, expr* comparators)
|
||||||
|
|
|
@ -1802,6 +1802,11 @@ expr_ty
|
||||||
YieldFrom(expr_ty value, int lineno, int col_offset, PyArena *arena)
|
YieldFrom(expr_ty value, int lineno, int col_offset, PyArena *arena)
|
||||||
{
|
{
|
||||||
expr_ty p;
|
expr_ty p;
|
||||||
|
if (!value) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"field value is required for YieldFrom");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5431,7 +5436,8 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena)
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
} else {
|
} else {
|
||||||
value = NULL;
|
PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from YieldFrom");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
*out = YieldFrom(value, lineno, col_offset, arena);
|
*out = YieldFrom(value, lineno, col_offset, arena);
|
||||||
if (*out == NULL) goto failed;
|
if (*out == NULL) goto failed;
|
||||||
|
|
|
@ -224,8 +224,7 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
|
||||||
case Yield_kind:
|
case Yield_kind:
|
||||||
return !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load);
|
return !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load);
|
||||||
case YieldFrom_kind:
|
case YieldFrom_kind:
|
||||||
return !exp->v.YieldFrom.value ||
|
return validate_expr(exp->v.YieldFrom.value, Load);
|
||||||
validate_expr(exp->v.YieldFrom.value, Load);
|
|
||||||
case Compare_kind:
|
case Compare_kind:
|
||||||
if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
|
if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
|
PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
|
||||||
|
|
|
@ -3341,27 +3341,24 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
|
||||||
case DictComp_kind:
|
case DictComp_kind:
|
||||||
return compiler_dictcomp(c, e);
|
return compiler_dictcomp(c, e);
|
||||||
case Yield_kind:
|
case Yield_kind:
|
||||||
case YieldFrom_kind: {
|
|
||||||
expr_ty value;
|
|
||||||
if (c->u->u_ste->ste_type != FunctionBlock)
|
if (c->u->u_ste->ste_type != FunctionBlock)
|
||||||
return compiler_error(c, "'yield' outside function");
|
return compiler_error(c, "'yield' outside function");
|
||||||
value = (e->kind == YieldFrom_kind) ? e->v.YieldFrom.value : e->v.Yield.value;
|
if (e->v.Yield.value) {
|
||||||
if (value) {
|
VISIT(c, expr, e->v.Yield.value);
|
||||||
VISIT(c, expr, value);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADDOP_O(c, LOAD_CONST, Py_None, consts);
|
ADDOP_O(c, LOAD_CONST, Py_None, consts);
|
||||||
}
|
}
|
||||||
if (e->kind == YieldFrom_kind) {
|
ADDOP(c, YIELD_VALUE);
|
||||||
ADDOP(c, GET_ITER);
|
break;
|
||||||
ADDOP_O(c, LOAD_CONST, Py_None, consts);
|
case YieldFrom_kind:
|
||||||
ADDOP(c, YIELD_FROM);
|
if (c->u->u_ste->ste_type != FunctionBlock)
|
||||||
}
|
return compiler_error(c, "'yield' outside function");
|
||||||
else {
|
VISIT(c, expr, e->v.YieldFrom.value);
|
||||||
ADDOP(c, YIELD_VALUE);
|
ADDOP(c, GET_ITER);
|
||||||
}
|
ADDOP_O(c, LOAD_CONST, Py_None, consts);
|
||||||
|
ADDOP(c, YIELD_FROM);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case Compare_kind:
|
case Compare_kind:
|
||||||
return compiler_compare(c, e);
|
return compiler_compare(c, e);
|
||||||
case Call_kind:
|
case Call_kind:
|
||||||
|
|
|
@ -1371,14 +1371,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
||||||
VISIT_QUIT(st, 0);
|
VISIT_QUIT(st, 0);
|
||||||
break;
|
break;
|
||||||
case Yield_kind:
|
case Yield_kind:
|
||||||
case YieldFrom_kind: {
|
if (e->v.Yield.value)
|
||||||
expr_ty value;
|
VISIT(st, expr, e->v.Yield.value);
|
||||||
value = (e->kind == YieldFrom_kind) ? e->v.YieldFrom.value : e->v.Yield.value;
|
st->st_cur->ste_generator = 1;
|
||||||
if (value)
|
break;
|
||||||
VISIT(st, expr, value);
|
case YieldFrom_kind:
|
||||||
|
VISIT(st, expr, e->v.YieldFrom.value);
|
||||||
st->st_cur->ste_generator = 1;
|
st->st_cur->ste_generator = 1;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case Compare_kind:
|
case Compare_kind:
|
||||||
VISIT(st, expr, e->v.Compare.left);
|
VISIT(st, expr, e->v.Compare.left);
|
||||||
VISIT_SEQ(st, expr, e->v.Compare.comparators);
|
VISIT_SEQ(st, expr, e->v.Compare.comparators);
|
||||||
|
|
Loading…
Reference in New Issue