bpo-10544: Deprecate "yield" in comprehensions and generator expressions. (GH-4579)

The current behaviour of yield expressions inside comprehensions  and
generator expressions is essentially an accident of implementation - it
arises implicitly from the way the compiler handles yield expressions inside
nested functions and generators.

Since the current behaviour wasn't deliberately designed, and is inherently
confusing, we're deprecating it, with no current plans to reintroduce it.
Instead, our advice will be to use a named nested generator definition
for cases where this behaviour is desired.
This commit is contained in:
Serhiy Storchaka 2017-12-01 06:54:17 +02:00 committed by Nick Coghlan
parent 6a89481680
commit 73a7e9b10b
6 changed files with 134 additions and 20 deletions

View file

@ -1734,7 +1734,6 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
e->lineno, e->col_offset)) {
return 0;
}
st->st_cur->ste_generator = is_generator;
if (outermost->is_async) {
st->st_cur->ste_coroutine = 1;
}
@ -1754,6 +1753,36 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,
if (value)
VISIT(st, expr, value);
VISIT(st, expr, elt);
if (st->st_cur->ste_generator) {
PyObject *msg = PyUnicode_FromString(
(e->kind == ListComp_kind) ? "'yield' inside list comprehension" :
(e->kind == SetComp_kind) ? "'yield' inside set comprehension" :
(e->kind == DictComp_kind) ? "'yield' inside dict comprehension" :
"'yield' inside generator expression");
if (msg == NULL) {
symtable_exit_block(st, (void *)e);
return 0;
}
if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning,
msg, st->st_filename, st->st_cur->ste_lineno,
NULL, NULL) == -1)
{
if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) {
/* Replace the DeprecationWarning exception with a SyntaxError
to get a more accurate error report */
PyErr_Clear();
PyErr_SetObject(PyExc_SyntaxError, msg);
PyErr_SyntaxLocationObject(st->st_filename,
st->st_cur->ste_lineno,
st->st_cur->ste_col_offset);
}
Py_DECREF(msg);
symtable_exit_block(st, (void *)e);
return 0;
}
Py_DECREF(msg);
}
st->st_cur->ste_generator |= is_generator;
return symtable_exit_block(st, (void *)e);
}