From: Dirkjan Ochtman Date: Tue, 29 Jul 2014 15:21:39 +0000 (+0200) Subject: Issue #21591: Handle exec backwards compatibility in the AST builder. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9b1d670361215f8d56de7a05cb1d430009735fd5;p=python 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. --- diff --git a/Misc/NEWS b/Misc/NEWS index bdd414ebeb..f6dda99278 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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 ------- diff --git a/Python/ast.c b/Python/ast.c index 80e6354ed4..ffd5679e09 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -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) diff --git a/Python/ceval.c b/Python/ceval.c index e00860831f..38f51faf69 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -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) {