[Python-checkins] bpo-38870: Don't omit parenthesis when unparsing a slice in ast.unparse

Batuhan Taskaya webhook-mailer at python.org
Mon May 18 16:48:56 EDT 2020


https://github.com/python/cpython/commit/c102a148256b00b7d48c51a1a97df19042e603de
commit: c102a148256b00b7d48c51a1a97df19042e603de
branch: master
author: Batuhan Taskaya <batuhanosmantaskaya at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-05-18T21:48:49+01:00
summary:

bpo-38870: Don't omit parenthesis when unparsing a slice in ast.unparse

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).

files:
M Lib/ast.py
M Lib/test/test_unparse.py

diff --git a/Lib/ast.py b/Lib/ast.py
index 2edb7171e9671..52e51b4858774 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -1356,10 +1356,20 @@ def visit_Call(self, node):
                 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)
diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py
index 6d828721b7740..bb725ced64db8 100644
--- a/Lib/test/test_unparse.py
+++ b/Lib/test/test_unparse.py
@@ -279,10 +279,13 @@ def test_dict_unpacking_in_dict(self):
         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 @@ def test_unary_op_factor(self):
         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."""
 



More information about the Python-checkins mailing list