]> git.madduck.net Git - etc/vim.git/commitdiff

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Make parentheses invisible recursively in atoms
authorŁukasz Langa <lukasz@langa.pl>
Mon, 7 May 2018 18:12:38 +0000 (11:12 -0700)
committerŁukasz Langa <lukasz@langa.pl>
Mon, 7 May 2018 18:13:55 +0000 (11:13 -0700)
This fixes non-deterministic formatting when multiple pairs of removable
parentheses are used.

Fixes #183

README.md
black.py
docs/reference/reference_functions.rst
tests/expression.diff
tests/expression.py

index a17fc3003d4b81663dc33ed7fd5992d9abf1d6a5..30990590403a52158789e1953f2bc522a64dcf06 100644 (file)
--- a/README.md
+++ b/README.md
@@ -538,9 +538,14 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
 
 ### 18.5a0 (unreleased)
 
-* Slices are now formatted according to PEP 8 (#178)
+* slices are now formatted according to PEP 8 (#178)
 
-* Empty parentheses in a class definition are removed (#145, #180)
+* empty parentheses in a class definition are now removed (#145, #180)
+
+* fixed an invalid trailing comma sometimes left in imports (#185)
+
+* fixed non-deterministic formatting when multiple pairs of removable parentheses
+  were used (#183)
 
 
 ### 18.4a4
index fd2b75ed2c1cf9d5ffb3759f142b6855b0a23b9e..34bdcf900dd50b2601a610d428006a1fdc06f59f 100644 (file)
--- a/black.py
+++ b/black.py
@@ -2187,17 +2187,7 @@ def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
     for child in list(node.children):
         if check_lpar:
             if child.type == syms.atom:
-                if not (
-                    is_empty_tuple(child)
-                    or is_one_tuple(child)
-                    or max_delimiter_priority_in_atom(child) >= COMMA_PRIORITY
-                ):
-                    first = child.children[0]
-                    last = child.children[-1]
-                    if first.type == token.LPAR and last.type == token.RPAR:
-                        # make parentheses invisible
-                        first.value = ""  # type: ignore
-                        last.value = ""  # type: ignore
+                maybe_make_parens_invisible_in_atom(child)
             elif is_one_tuple(child):
                 # wrap child in visible parentheses
                 lpar = Leaf(token.LPAR, "(")
@@ -2214,6 +2204,29 @@ def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
         check_lpar = isinstance(child, Leaf) and child.value in parens_after
 
 
+def maybe_make_parens_invisible_in_atom(node: LN) -> bool:
+    """If it's safe, make the parens in the atom `node` invisible, recusively."""
+    if (
+        node.type != syms.atom
+        or is_empty_tuple(node)
+        or is_one_tuple(node)
+        or max_delimiter_priority_in_atom(node) >= COMMA_PRIORITY
+    ):
+        return False
+
+    first = node.children[0]
+    last = node.children[-1]
+    if first.type == token.LPAR and last.type == token.RPAR:
+        # make parentheses invisible
+        first.value = ""  # type: ignore
+        last.value = ""  # type: ignore
+        if len(node.children) > 1:
+            maybe_make_parens_invisible_in_atom(node.children[1])
+        return True
+
+    return False
+
+
 def is_empty_tuple(node: LN) -> bool:
     """Return True if `node` holds an empty tuple."""
     return (
index d0ded95e4a6d1110640786b431832dbde973f94d..ede46a4507b418ddeed6103e989c9e37d533eb98 100644 (file)
@@ -98,6 +98,8 @@ Utilities
 
 .. autofunction:: black.make_comment
 
+.. autofunction:: black.maybe_make_parens_invisible_in_atom
+
 .. autofunction:: black.max_delimiter_priority_in_atom
 
 .. autofunction:: black.normalize_prefix
index 309a480c2b0219c6fb53001ecdbc09ed35f2800d..ad5e934adee206f7bd57a08758399573cd59950e 100644 (file)
  ]
  slice[0]
  slice[0:1]
-@@ -123,88 +145,114 @@
+@@ -123,91 +145,119 @@
  numpy[-(c + 1) :, d]
  numpy[:, l[-2]]
  numpy[:, ::-1]
 +print(*[] or [1])
  print(**{1: 3} if False else {x: x for x in range(3)})
 -print(* lambda x: x)
+-assert(not Test),("Short message")
+-assert this is ComplexTest and not requirements.fit_in_a_single_line(force=False), "Short message"
+-assert(((parens is TooMany)))
 -for x, in (1,), (2,), (3,): ...
 -for y in (): ...
 -for z in (i for i in (1, 2, 3)): ...
 -    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /
 -    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 +print(*lambda x: x)
++assert not Test, "Short message"
++assert (
++    this is ComplexTest and not requirements.fit_in_a_single_line(force=False)
++), "Short message"
++assert parens is TooMany
 +for (x,) in (1,), (2,), (3,):
 +    ...
 +for y in ():
index d170a665554dff8c8c8348b90eb9348c0547390a..2c92c0e8632fcf6dcf5cd638a356e2ca9d51324f 100644 (file)
@@ -163,6 +163,9 @@ async def f():
 print(* [] or [1])
 print(**{1: 3} if False else {x: x for x in range(3)})
 print(* lambda x: x)
+assert(not Test),("Short message")
+assert this is ComplexTest and not requirements.fit_in_a_single_line(force=False), "Short message"
+assert(((parens is TooMany)))
 for x, in (1,), (2,), (3,): ...
 for y in (): ...
 for z in (i for i in (1, 2, 3)): ...
@@ -419,6 +422,11 @@ async def f():
 print(*[] or [1])
 print(**{1: 3} if False else {x: x for x in range(3)})
 print(*lambda x: x)
+assert not Test, "Short message"
+assert (
+    this is ComplexTest and not requirements.fit_in_a_single_line(force=False)
+), "Short message"
+assert parens is TooMany
 for (x,) in (1,), (2,), (3,):
     ...
 for y in ():