]> granicus.if.org Git - python/commitdiff
Issue #21591: Handle exec backwards compatibility in the AST builder.
authorDirkjan Ochtman <dirkjan@ochtman.nl>
Tue, 29 Jul 2014 15:21:39 +0000 (17:21 +0200)
committerDirkjan Ochtman <dirkjan@ochtman.nl>
Tue, 29 Jul 2014 15:21:39 +0000 (17:21 +0200)
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
Python/ast.c
Python/ceval.c

index bdd414ebeb93fb3acef4080b87ae70a2220927b8..f6dda992784e614069153999fddf27889c43b149 100644 (file)
--- 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
 -------
 
index 80e6354ed4a2def26bca37ecfbec20006a5c46a1..ffd5679e09bc09fdafd875e8d4eb8db962b10391 100644 (file)
@@ -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)
index e00860831f15f3d4425db0f42b167628480da45b..38f51faf69c38777705e7228ab36f718993aa926 100644 (file)
@@ -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) {