Commit b0f4c89b authored by Dirkjan Ochtman's avatar Dirkjan Ochtman

Issue #21591: Handle exec backwards compatibility in the AST builder.

Instead of deferring until runtime. This makes sure we hit the right
conditions in dealing with unqualified exec statements.

Reviewed by Victor Stinner. Test follows in a later commit.
parent b2291231
......@@ -10,6 +10,9 @@ What's New in Python 2.7.9?
Core and Builtins
-----------------
- Issue #21591: Correctly handle qualified exec statements in tuple form by
moving compatibility layer from run-time to AST transformation.
Library
-------
......
......@@ -2679,6 +2679,18 @@ ast_for_exec_stmt(struct compiling *c, const node *n)
expr1 = ast_for_expr(c, CHILD(n, 1));
if (!expr1)
return NULL;
if (expr1->kind == Tuple_kind && n_children < 4 &&
(asdl_seq_LEN(expr1->v.Tuple.elts) == 2 ||
asdl_seq_LEN(expr1->v.Tuple.elts) == 3)) {
/* Backwards compatibility: pass exec args as a tuple */
globals = (expr_ty) asdl_seq_GET(expr1->v.Tuple.elts, 1);
if (asdl_seq_LEN(expr1->v.Tuple.elts) == 3) {
locals = (expr_ty) asdl_seq_GET(expr1->v.Tuple.elts, 2);
}
expr1 = (expr_ty) asdl_seq_GET(expr1->v.Tuple.elts, 0);
}
if (n_children >= 4) {
globals = ast_for_expr(c, CHILD(n, 3));
if (!globals)
......
......@@ -4673,18 +4673,9 @@ static int
exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
PyObject *locals)
{
int n;
PyObject *v;
int plain = 0;
if (PyTuple_Check(prog) && globals == Py_None && locals == Py_None &&
((n = PyTuple_Size(prog)) == 2 || n == 3)) {
/* Backward compatibility hack */
globals = PyTuple_GetItem(prog, 1);
if (n == 3)
locals = PyTuple_GetItem(prog, 2);
prog = PyTuple_GetItem(prog, 0);
}
if (globals == Py_None) {
globals = PyEval_GetGlobals();
if (locals == Py_None) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment