From a7a228d428022cf0f0c03b04ca70cc19f1cb3fbc Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sun, 8 Mar 2020 14:13:32 +0300 Subject: [PATCH] bpo-38870: Simplify tuple like interleaves --- Lib/ast.py | 37 ++++++++++++++----------------------- Lib/test/test_unparse.py | 34 ++++++++++++++++++++-------------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index 2719f6ff7ac593..9a3d3806eb8ca7 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -613,6 +613,16 @@ def interleave(self, inter, f, seq): inter() f(x) + def items_view(self, traverser, items): + """Traverse and separate the given *items* with a comma and append it to + the buffer. If *items* is a single item sequence, a trailing comma + will be added.""" + if len(items) == 1: + traverser(items[0]) + self.write(",") + else: + self.interleave(lambda: self.write(", "), traverser, items) + def fill(self, text=""): """Indent a piece of text and append it, according to the current indentation level""" @@ -1020,11 +1030,7 @@ def visit_Constant(self, node): value = node.value if isinstance(value, tuple): with self.delimit("(", ")"): - if len(value) == 1: - self._write_constant(value[0]) - self.write(",") - else: - self.interleave(lambda: self.write(", "), self._write_constant, value) + self.items_view(self._write_constant, value) elif value is ...: self.write("...") else: @@ -1116,12 +1122,7 @@ def write_item(item): def visit_Tuple(self, node): with self.delimit("(", ")"): - if len(node.elts) == 1: - elt = node.elts[0] - self.traverse(elt) - self.write(",") - else: - self.interleave(lambda: self.write(", "), self.traverse, node.elts) + self.items_view(self.traverse, node.elts) unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"} unop_precedence = { @@ -1264,12 +1265,7 @@ def visit_Subscript(self, node): if (isinstance(node.slice, Index) and isinstance(node.slice.value, Tuple) and node.slice.value.elts): - if len(node.slice.value.elts) == 1: - elt = node.slice.value.elts[0] - self.traverse(elt) - self.write(",") - else: - self.interleave(lambda: self.write(", "), self.traverse, node.slice.value.elts) + self.items_view(self.traverse, node.slice.value.elts) else: self.traverse(node.slice) @@ -1296,12 +1292,7 @@ def visit_Slice(self, node): self.traverse(node.step) def visit_ExtSlice(self, node): - if len(node.dims) == 1: - elt = node.dims[0] - self.traverse(elt) - self.write(",") - else: - self.interleave(lambda: self.write(", "), self.traverse, node.dims) + self.items_view(self.traverse, node.dims) def visit_arg(self, node): self.write(node.arg) diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index d33f32e2a7fe93..3d87cfb6daeef8 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -280,6 +280,20 @@ 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): + self.check_ast_roundtrip("a[i]") + self.check_ast_roundtrip("a[i,]") + self.check_ast_roundtrip("a[i, j]") + self.check_ast_roundtrip("a[()]") + self.check_ast_roundtrip("a[i:j]") + self.check_ast_roundtrip("a[:j]") + self.check_ast_roundtrip("a[i:]") + self.check_ast_roundtrip("a[i:j:k]") + self.check_ast_roundtrip("a[:j:k]") + self.check_ast_roundtrip("a[i::k]") + self.check_ast_roundtrip("a[i:j,]") + self.check_ast_roundtrip("a[i:j, k]") + def test_invalid_raise(self): self.check_invalid(ast.Raise(exc=None, cause=ast.Name(id="X"))) @@ -310,6 +324,12 @@ def test_docstrings(self): # check as Module docstrings for easy testing self.check_ast_roundtrip(f"'{docstring}'") + def test_constant_tuples(self): + self.check_src_roundtrip(ast.Constant(value=(1,), kind=None), "(1,)") + self.check_src_roundtrip( + ast.Constant(value=(1, 2, 3), kind=None), "(1, 2, 3)" + ) + class CosmeticTestCase(ASTTestCase): """Test if there are cosmetic issues caused by unnecesary additions""" @@ -344,20 +364,6 @@ def test_simple_expressions_parens(self): self.check_src_roundtrip("call((yield x))") self.check_src_roundtrip("return x + (yield x)") - def test_subscript(self): - self.check_src_roundtrip("a[i]") - self.check_src_roundtrip("a[i,]") - self.check_src_roundtrip("a[i, j]") - self.check_src_roundtrip("a[()]") - self.check_src_roundtrip("a[i:j]") - self.check_src_roundtrip("a[:j]") - self.check_src_roundtrip("a[i:]") - self.check_src_roundtrip("a[i:j:k]") - self.check_src_roundtrip("a[:j:k]") - self.check_src_roundtrip("a[i::k]") - self.check_src_roundtrip("a[i:j,]") - self.check_src_roundtrip("a[i:j, k]") - def test_docstrings(self): docstrings = ( '"""simple doc string"""',