]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-38870: Don't omit parenthesis when unparsing a slice in ast.unparse
authorBatuhan Taskaya <batuhanosmantaskaya@gmail.com>
Mon, 18 May 2020 20:48:49 +0000 (23:48 +0300)
committerGitHub <noreply@github.com>
Mon, 18 May 2020 20:48:49 +0000 (21:48 +0100)
When unparsing a non-empty tuple, the parentheses can be safely
omitted if there aren't any elements that explicitly require them (such as starred expressions).

Lib/ast.py
Lib/test/test_unparse.py

index 2edb7171e967190bdcba5e108db02687320c037d..52e51b485877478972e23e76ed3b74145d2ff65e 100644 (file)
@@ -1356,10 +1356,20 @@ class _Unparser(NodeVisitor):
                 self.traverse(e)
 
     def visit_Subscript(self, node):
+        def is_simple_tuple(slice_value):
+            # when unparsing a non-empty tuple, the parantheses can be safely
+            # omitted if there aren't any elements that explicitly requires
+            # parantheses (such as starred expressions).
+            return (
+                isinstance(slice_value, Tuple)
+                and slice_value.elts
+                and not any(isinstance(elt, Starred) for elt in slice_value.elts)
+            )
+
         self.set_precedence(_Precedence.ATOM, node.value)
         self.traverse(node.value)
         with self.delimit("[", "]"):
-            if isinstance(node.slice, Tuple) and node.slice.elts:
+            if is_simple_tuple(node.slice):
                 self.items_view(self.traverse, node.slice.elts)
             else:
                 self.traverse(node.slice)
index 6d828721b7740e9e09ca86c047373778246927ce..bb725ced64db8c44de635a18c883be626d93e344 100644 (file)
@@ -279,10 +279,13 @@ class UnparseTestCase(ASTTestCase):
         self.check_ast_roundtrip(r"""{**{'y': 2}, 'x': 1}""")
         self.check_ast_roundtrip(r"""{**{'y': 2}, **{'x': 1}}""")
 
-    def test_ext_slices(self):
+    def test_slices(self):
         self.check_ast_roundtrip("a[i]")
         self.check_ast_roundtrip("a[i,]")
         self.check_ast_roundtrip("a[i, j]")
+        self.check_ast_roundtrip("a[(*a,)]")
+        self.check_ast_roundtrip("a[(a:=b)]")
+        self.check_ast_roundtrip("a[(a:=b,c)]")
         self.check_ast_roundtrip("a[()]")
         self.check_ast_roundtrip("a[i:j]")
         self.check_ast_roundtrip("a[:j]")
@@ -470,6 +473,11 @@ class CosmeticTestCase(ASTTestCase):
         for prefix in ("not",):
             self.check_src_roundtrip(f"{prefix} 1")
 
+    def test_slices(self):
+        self.check_src_roundtrip("a[1]")
+        self.check_src_roundtrip("a[1, 2]")
+        self.check_src_roundtrip("a[(1, *a)]")
+
 class DirectoryTestCase(ASTTestCase):
     """Test roundtrip behaviour on all files in Lib and Lib/test."""