implement tuple compatibility form of Py2 exec statement
authorStefan Behnel <stefan_ml@behnel.de>
Sat, 9 Feb 2013 14:07:26 +0000 (15:07 +0100)
committerStefan Behnel <stefan_ml@behnel.de>
Sat, 9 Feb 2013 14:07:26 +0000 (15:07 +0100)
Cython/Compiler/Parsing.py
tests/errors/exec_errors.pyx [new file with mode: 0644]
tests/run/exectest.pyx

index dcf20d7..9c7b2d3 100644 (file)
@@ -1157,14 +1157,28 @@ def p_exec_statement(s):
     # s.sy == 'exec'
     pos = s.position()
     s.next()
-    args = [ p_bit_expr(s) ]
+    code = p_bit_expr(s)
+    if isinstance(code, ExprNodes.TupleNode):
+        # Py3 compatibility syntax
+        tuple_variant = True
+        args = code.args
+        if len(args) not in (2, 3):
+            s.error("expected tuple of length 2 or 3, got length %d" % len(args),
+                    pos=pos, fatal=False)
+            args = [code]
+    else:
+        tuple_variant = False
+        args = [code]
     if s.sy == 'in':
+        if tuple_variant:
+            s.error("tuple variant of exec does not support additional 'in' arguments",
+                    fatal=False)
         s.next()
         args.append(p_test(s))
         if s.sy == ',':
             s.next()
             args.append(p_test(s))
-    return Nodes.ExecStatNode(pos, args = args)
+    return Nodes.ExecStatNode(pos, args=args)
 
 def p_del_statement(s):
     # s.sy == 'del'
diff --git a/tests/errors/exec_errors.pyx b/tests/errors/exec_errors.pyx
new file mode 100644 (file)
index 0000000..17b1504
--- /dev/null
@@ -0,0 +1,24 @@
+# mode: error
+# tag: exec
+
+def test_exec_tuples():
+    exec()
+    exec(1,)
+    exec(1,2,3,4)
+
+def test_exec_tuples_with_in(d1, d2):
+    exec(1,2) in d1
+    exec(1,2,3) in d1
+    exec(1,2) in d1, d2
+    exec(1,2,3) in d1, d2
+
+
+_ERRORS = """
+ 5:4: expected tuple of length 2 or 3, got length 0
+ 6:4: expected tuple of length 2 or 3, got length 1
+ 7:4: expected tuple of length 2 or 3, got length 4
+10:14: tuple variant of exec does not support additional 'in' arguments
+11:16: tuple variant of exec does not support additional 'in' arguments
+12:14: tuple variant of exec does not support additional 'in' arguments
+13:16: tuple variant of exec does not support additional 'in' arguments
+"""
index 5a5cebe..d7208b2 100644 (file)
@@ -86,6 +86,24 @@ def test_dict_scope3(d1, d2):
 def test_dict_scope_ref(d1, d2):
     exec u"b=a+c" in d1, d2
 
+def test_dict_scope_tuple2():
+    """
+    >>> test_dict_scope_tuple2()
+    2
+    """
+    cdef dict d = {}
+    exec(u"b=1+1", d)   # Py3 compatibility syntax
+    return d[u'b']
+
+def test_dict_scope_tuple3(d1, d2):
+    """
+    >>> d1, d2 = {}, {}
+    >>> test_dict_scope_tuple3(d1, d2)
+    >>> (d1.get('b'), d2.get('b'))
+    (None, 2)
+    """
+    exec(u"b=1+1", d1, d2)
+
 def test_def(d, varref):
     exec u"""
 def test():