Skip to content

Commit c102a14

Browse files
authored
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).
1 parent 75b863a commit c102a14

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

Lib/ast.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1356,10 +1356,20 @@ def visit_Call(self, node):
13561356
self.traverse(e)
13571357

13581358
def visit_Subscript(self, node):
1359+
def is_simple_tuple(slice_value):
1360+
# when unparsing a non-empty tuple, the parantheses can be safely
1361+
# omitted if there aren't any elements that explicitly requires
1362+
# parantheses (such as starred expressions).
1363+
return (
1364+
isinstance(slice_value, Tuple)
1365+
and slice_value.elts
1366+
and not any(isinstance(elt, Starred) for elt in slice_value.elts)
1367+
)
1368+
13591369
self.set_precedence(_Precedence.ATOM, node.value)
13601370
self.traverse(node.value)
13611371
with self.delimit("[", "]"):
1362-
if isinstance(node.slice, Tuple) and node.slice.elts:
1372+
if is_simple_tuple(node.slice):
13631373
self.items_view(self.traverse, node.slice.elts)
13641374
else:
13651375
self.traverse(node.slice)

Lib/test/test_unparse.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,13 @@ def test_dict_unpacking_in_dict(self):
279279
self.check_ast_roundtrip(r"""{**{'y': 2}, 'x': 1}""")
280280
self.check_ast_roundtrip(r"""{**{'y': 2}, **{'x': 1}}""")
281281

282-
def test_ext_slices(self):
282+
def test_slices(self):
283283
self.check_ast_roundtrip("a[i]")
284284
self.check_ast_roundtrip("a[i,]")
285285
self.check_ast_roundtrip("a[i, j]")
286+
self.check_ast_roundtrip("a[(*a,)]")
287+
self.check_ast_roundtrip("a[(a:=b)]")
288+
self.check_ast_roundtrip("a[(a:=b,c)]")
286289
self.check_ast_roundtrip("a[()]")
287290
self.check_ast_roundtrip("a[i:j]")
288291
self.check_ast_roundtrip("a[:j]")
@@ -470,6 +473,11 @@ def test_unary_op_factor(self):
470473
for prefix in ("not",):
471474
self.check_src_roundtrip(f"{prefix} 1")
472475

476+
def test_slices(self):
477+
self.check_src_roundtrip("a[1]")
478+
self.check_src_roundtrip("a[1, 2]")
479+
self.check_src_roundtrip("a[(1, *a)]")
480+
473481
class DirectoryTestCase(ASTTestCase):
474482
"""Test roundtrip behaviour on all files in Lib and Lib/test."""
475483

0 commit comments

Comments
 (0)