[pypy-commit] pypy py3.6: Empty tuples

arigo pypy.commits at gmail.com
Mon May 14 09:49:13 EDT 2018


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.6
Changeset: r94582:3131adbe1e58
Date: 2018-05-14 15:48 +0200
http://bitbucket.org/pypy/pypy/changeset/3131adbe1e58/

Log:	Empty tuples

diff --git a/pypy/interpreter/astcompiler/asthelpers.py b/pypy/interpreter/astcompiler/asthelpers.py
--- a/pypy/interpreter/astcompiler/asthelpers.py
+++ b/pypy/interpreter/astcompiler/asthelpers.py
@@ -83,10 +83,7 @@
         if self.elts:
             for elt in self.elts:
                 elt.set_context(space, ctx)
-            self.ctx = ctx
-        else:
-            # Assignment to () raises an error.
-            ast.expr.set_context(self, space, ctx)
+        self.ctx = ctx
 
 class __extend__(ast.Lambda):
 
diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -287,6 +287,9 @@
 
     def visit_Tuple(self, tup):
         """Try to turn tuple building into a constant."""
+        if tup.ctx != ast.Load:
+            return tup   # Don't do the rest for assignment or delete targets.
+                         # It would replace Tuple([]) with Constant('()')!
         if tup.elts:
             consts_w = [None]*len(tup.elts)
             for i in range(len(tup.elts)):
diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -810,7 +810,6 @@
             ("{x : x for x in z}", "dict comprehension"),
             ("'str'", "literal"),
             ("b'bytes'", "literal"),
-            ("()", "()"),
             ("23", "literal"),
             ("{}", "literal"),
             ("{1, 2, 3}", "literal"),
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -129,7 +129,7 @@
         self.simple_test(stmt, "type(x)", int)
 
     def test_tuple_assign(self):
-        yield self.error_test, "() = 1", SyntaxError
+        yield self.simple_test, "() = []", "1", 1
         yield self.simple_test, "x,= 1,", "x", 1
         yield self.simple_test, "x,y = 1,2", "x,y", (1, 2)
         yield self.simple_test, "x,y,z = 1,2,3", "x,y,z", (1, 2, 3)
@@ -1482,3 +1482,12 @@
             return f'ab{x}cd'
         """
         code, blocks = generate_function_code(source, self.space)
+
+    def test_empty_tuple_target(self):
+        source = """def f():
+            () = ()
+            del ()
+            [] = []
+            del []
+        """
+        generate_function_code(source, self.space)
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -783,21 +783,6 @@
         assert isinstance(code, PyCode)
         assert code.co_filename == '<filename2>'
 
-    def test_with_empty_tuple(self):
-        source = py.code.Source("""
-        from __future__ import with_statement
-
-        with x as ():
-            pass
-        """)
-        try:
-            self.compiler.compile(str(source), '<filename>', 'exec', 0)
-        except OperationError as e:
-            if not e.match(self.space, self.space.w_SyntaxError):
-                raise
-        else:
-            py.test.fail("Did not raise")
-
     def test_assign_to_yield(self):
         code = 'def f(): (yield bar) += y'
         try:
diff --git a/pypy/interpreter/test/test_syntax.py b/pypy/interpreter/test/test_syntax.py
--- a/pypy/interpreter/test/test_syntax.py
+++ b/pypy/interpreter/test/test_syntax.py
@@ -752,6 +752,33 @@
         exc = raises(SyntaxError, compile, code, 'foo', 'exec')
         assert exc.value.offset in (19, 20) # pypy, cpython
 
+    def test_empty_tuple_target(self): """
+        def f(n):
+            () = ()
+            ((), ()) = [[], []]
+            del ()
+            del ((), ())
+            [] = {}
+            ([], ()) = [[], ()]
+            [[], ()] = ((), [])
+            del []
+            del [[], ()]
+            for () in [(), []]: pass
+            for [] in ([],): pass
+            class Zen:
+                def __enter__(self): return ()
+                def __exit__(self, *args): pass
+            with Zen() as (): pass
+            () = [2, 3] * n
+        f(0)
+        try:
+            f(5)
+        except ValueError:
+            pass
+        else:
+            raise AssertionError("should have raised")
+        """
+
 
 if __name__ == '__main__':
     # only to check on top of CPython (you need 2.4)


More information about the pypy-commit mailing list