From 64c5b2544073a90298e4ce1e6bb6bbb222db4532 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 9 Feb 2013 15:07:26 +0100 Subject: [PATCH] implement tuple compatibility form of Py2 exec statement --- Cython/Compiler/Parsing.py | 18 ++++++++++++++++-- tests/errors/exec_errors.pyx | 24 ++++++++++++++++++++++++ tests/run/exectest.pyx | 18 ++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/errors/exec_errors.pyx diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index dcf20d7..9c7b2d3 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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 index 0000000..17b1504 --- /dev/null +++ b/tests/errors/exec_errors.pyx @@ -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 +""" diff --git a/tests/run/exectest.pyx b/tests/run/exectest.pyx index 5a5cebe..d7208b2 100644 --- a/tests/run/exectest.pyx +++ b/tests/run/exectest.pyx @@ -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(): -- 2.7.4