From 9b1d670361215f8d56de7a05cb1d430009735fd5 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 29 Jul 2014 17:21:39 +0200 Subject: [PATCH] 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. --- Misc/NEWS | 3 +++ Python/ast.c | 12 ++++++++++++ Python/ceval.c | 9 --------- 3 files changed, 15 insertions(+), 9 deletions(-) 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) { -- 2.50.1