]> 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:

Fix instability due to trailing comma logic (#2572)
authorNipunn Koorapati <nipunn1313@gmail.com>
Sat, 29 Jan 2022 02:13:18 +0000 (18:13 -0800)
committerGitHub <noreply@github.com>
Sat, 29 Jan 2022 02:13:18 +0000 (18:13 -0800)
It was causing stability issues because the first pass
could cause a "magic trailing comma" to appear, meaning
that the second pass might get a different result. It's
not critical.

Some things format differently (with extra parens)

CHANGES.md
src/black/__init__.py
src/black/linegen.py
src/black/lines.py
src/black/nodes.py
tests/data/function_trailing_comma.py
tests/data/long_strings_flag_disabled.py
tests/data/torture.py
tests/data/trailing_comma_optional_parens1.py
tests/data/trailing_comma_optional_parens2.py
tests/data/trailing_comma_optional_parens3.py

index b57a360f1bce3e6cc4263b35868b6f29f0c453d9..6775cee14e80f481ab3c14b39ea4230f2a6d8854 100644 (file)
@@ -139,6 +139,7 @@ and the first release covered by our new stability policy.
   when `--target-version py310` is explicitly specified (#2586)
 - Add support for parenthesized with (#2586)
 - Declare support for Python 3.10 for running Black (#2562)
+- Fix unstable black runs around magic trailing comma (#2572)
 
 ### Integrations
 
index 769e693ed2386659522f2f2fdda6e5516f8883fb..6192f5c0f8edce744b5094b07d79aec59474137c 100644 (file)
@@ -1332,7 +1332,7 @@ def get_future_imports(node: Node) -> Set[str]:
     return imports
 
 
-def assert_equivalent(src: str, dst: str, *, pass_num: int = 1) -> None:
+def assert_equivalent(src: str, dst: str) -> None:
     """Raise AssertionError if `src` and `dst` aren't equivalent."""
     try:
         src_ast = parse_ast(src)
@@ -1349,7 +1349,7 @@ def assert_equivalent(src: str, dst: str, *, pass_num: int = 1) -> None:
     except Exception as exc:
         log = dump_to_file("".join(traceback.format_tb(exc.__traceback__)), dst)
         raise AssertionError(
-            f"INTERNAL ERROR: Black produced invalid code on pass {pass_num}: {exc}. "
+            f"INTERNAL ERROR: Black produced invalid code: {exc}. "
             "Please report a bug on https://github.com/psf/black/issues.  "
             f"This invalid output might be helpful: {log}"
         ) from None
@@ -1360,7 +1360,7 @@ def assert_equivalent(src: str, dst: str, *, pass_num: int = 1) -> None:
         log = dump_to_file(diff(src_ast_str, dst_ast_str, "src", "dst"))
         raise AssertionError(
             "INTERNAL ERROR: Black produced code that is not equivalent to the"
-            f" source on pass {pass_num}.  Please report a bug on "
+            f" source.  Please report a bug on "
             f"https://github.com/psf/black/issues.  This diff might be helpful: {log}"
         ) from None
 
index 495d3230f8fed640f421185fc962ec0714520e4d..4dc242a1dfe05b9f8ef7ff53b26333073469cf57 100644 (file)
@@ -543,7 +543,7 @@ def right_hand_split(
         # there are no standalone comments in the body
         and not body.contains_standalone_comments(0)
         # and we can actually remove the parens
-        and can_omit_invisible_parens(body, line_length, omit_on_explode=omit)
+        and can_omit_invisible_parens(body, line_length)
     ):
         omit = {id(closing_bracket), *omit}
         try:
index 1c4e38a96c14bdcbf4d8d74f79121d677987a41e..f35665c8e0c5afa0eba3d0385c4153609e13c8f6 100644 (file)
@@ -3,7 +3,6 @@ import itertools
 import sys
 from typing import (
     Callable,
-    Collection,
     Dict,
     Iterator,
     List,
@@ -22,7 +21,7 @@ from black.mode import Mode
 from black.nodes import STANDALONE_COMMENT, TEST_DESCENDANTS
 from black.nodes import BRACKETS, OPENING_BRACKETS, CLOSING_BRACKETS
 from black.nodes import syms, whitespace, replace_child, child_towards
-from black.nodes import is_multiline_string, is_import, is_type_comment, last_two_except
+from black.nodes import is_multiline_string, is_import, is_type_comment
 from black.nodes import is_one_tuple_between
 
 # types
@@ -645,7 +644,6 @@ def can_be_split(line: Line) -> bool:
 def can_omit_invisible_parens(
     line: Line,
     line_length: int,
-    omit_on_explode: Collection[LeafID] = (),
 ) -> bool:
     """Does `line` have a shape safe to reformat without optional parens around it?
 
@@ -683,12 +681,6 @@ def can_omit_invisible_parens(
 
     penultimate = line.leaves[-2]
     last = line.leaves[-1]
-    if line.magic_trailing_comma:
-        try:
-            penultimate, last = last_two_except(line.leaves, omit=omit_on_explode)
-        except LookupError:
-            # Turns out we'd omit everything.  We cannot skip the optional parentheses.
-            return False
 
     if (
         last.type == token.RPAR
@@ -710,10 +702,6 @@ def can_omit_invisible_parens(
             # unnecessary.
             return True
 
-        if line.magic_trailing_comma and penultimate.type == token.COMMA:
-            # The rightmost non-omitted bracket pair is the one we want to explode on.
-            return True
-
         if _can_omit_closing_paren(line, last=last, line_length=line_length):
             return True
 
index 7466670be5a9864669790b0bd6948217441c435b..f130bff990e1622c3555f65262f12c0e7d65ff2d 100644 (file)
@@ -4,13 +4,11 @@ blib2to3 Node/Leaf transformation-related utility functions.
 
 import sys
 from typing import (
-    Collection,
     Generic,
     Iterator,
     List,
     Optional,
     Set,
-    Tuple,
     TypeVar,
     Union,
 )
@@ -439,27 +437,6 @@ def prev_siblings_are(node: Optional[LN], tokens: List[Optional[NodeType]]) -> b
     return prev_siblings_are(node.prev_sibling, tokens[:-1])
 
 
-def last_two_except(leaves: List[Leaf], omit: Collection[LeafID]) -> Tuple[Leaf, Leaf]:
-    """Return (penultimate, last) leaves skipping brackets in `omit` and contents."""
-    stop_after: Optional[Leaf] = None
-    last: Optional[Leaf] = None
-    for leaf in reversed(leaves):
-        if stop_after:
-            if leaf is stop_after:
-                stop_after = None
-            continue
-
-        if last:
-            return leaf, last
-
-        if id(leaf) in omit:
-            stop_after = leaf.opening_bracket
-        else:
-            last = leaf
-    else:
-        raise LookupError("Last two leaves were also skipped")
-
-
 def parent_type(node: Optional[LN]) -> Optional[NodeType]:
     """
     Returns:
index 02078219e8255f00559ac63391af8394bab63115..429eb0e330f9e31fe9be16ac3d89c775659b42e1 100644 (file)
@@ -89,16 +89,19 @@ def f(
         "a": 1,
         "b": 2,
     }["a"]
-    if a == {
-        "a": 1,
-        "b": 2,
-        "c": 3,
-        "d": 4,
-        "e": 5,
-        "f": 6,
-        "g": 7,
-        "h": 8,
-    }["a"]:
+    if (
+        a
+        == {
+            "a": 1,
+            "b": 2,
+            "c": 3,
+            "d": 4,
+            "e": 5,
+            "f": 6,
+            "g": 7,
+            "h": 8,
+        }["a"]
+    ):
         pass
 
 
index ef3094fd77969401ff8f99067f61e3ec769fc2fc..db3954e3abd7ea472f3e090c11f5839f0bcc5c6c 100644 (file)
@@ -133,11 +133,14 @@ old_fmt_string2 = "This is a %s %s %s %s" % (
     "Use f-strings instead!",
 )
 
-old_fmt_string3 = "Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s" % (
-    "really really really really really",
-    "old",
-    "way to format strings!",
-    "Use f-strings instead!",
+old_fmt_string3 = (
+    "Whereas only the strings after the percent sign were long in the last example, this example uses a long initial string as well. This is another %s %s %s %s"
+    % (
+        "really really really really really",
+        "old",
+        "way to format strings!",
+        "Use f-strings instead!",
+    )
 )
 
 fstring = f"f-strings definitely make things more {difficult} than they need to be for {{black}}. But boy they sure are handy. The problem is that some lines will need to have the 'f' whereas others do not. This {line}, for example, needs one."
index 79a44c2e34c9c800606533ad89299ce76513be0f..7cabd4c163fb95224b5efdaec56603a711eefeab 100644 (file)
@@ -31,20 +31,17 @@ importA
     ** 101234234242352525425252352352525234890264906820496920680926538059059209922523523525
 )  #
 
-assert (
-    sort_by_dependency(
-        {
-            "1": {"2", "3"},
-            "2": {"2a", "2b"},
-            "3": {"3a", "3b"},
-            "2a": set(),
-            "2b": set(),
-            "3a": set(),
-            "3b": set(),
-        }
-    )
-    == ["2a", "2b", "2", "3a", "3b", "3", "1"]
-)
+assert sort_by_dependency(
+    {
+        "1": {"2", "3"},
+        "2": {"2a", "2b"},
+        "3": {"3a", "3b"},
+        "2a": set(),
+        "2b": set(),
+        "3a": set(),
+        "3b": set(),
+    }
+) == ["2a", "2b", "2", "3a", "3b", "3", "1"]
 
 importA
 0
index f9f4ae5e0236286894ea9a6cebf1e3826eb400a6..85aa8badb261652e60427d43a5796d42e2e72bec 100644 (file)
@@ -2,6 +2,10 @@ if e1234123412341234.winerror not in (_winapi.ERROR_SEM_TIMEOUT,
                         _winapi.ERROR_PIPE_BUSY) or _check_timeout(t):
     pass
 
+if x:
+    if y:
+        new_id = max(Vegetable.objects.order_by('-id')[0].id,
+                     Mineral.objects.order_by('-id')[0].id) + 1
 
 class X:
     def get_help_text(self):
@@ -23,39 +27,37 @@ class A:
 
 # output
 
-if (
-    e1234123412341234.winerror
-    not in (
-        _winapi.ERROR_SEM_TIMEOUT,
-        _winapi.ERROR_PIPE_BUSY,
-    )
-    or _check_timeout(t)
-):
+if e1234123412341234.winerror not in (
+    _winapi.ERROR_SEM_TIMEOUT,
+    _winapi.ERROR_PIPE_BUSY,
+) or _check_timeout(t):
     pass
 
+if x:
+    if y:
+        new_id = (
+            max(
+                Vegetable.objects.order_by("-id")[0].id,
+                Mineral.objects.order_by("-id")[0].id,
+            )
+            + 1
+        )
+
 
 class X:
     def get_help_text(self):
-        return (
-            ngettext(
-                "Your password must contain at least %(min_length)d character.",
-                "Your password must contain at least %(min_length)d characters.",
-                self.min_length,
-            )
-            % {"min_length": self.min_length}
-        )
+        return ngettext(
+            "Your password must contain at least %(min_length)d character.",
+            "Your password must contain at least %(min_length)d characters.",
+            self.min_length,
+        ) % {"min_length": self.min_length}
 
 
 class A:
     def b(self):
-        if (
-            self.connection.mysql_is_mariadb
-            and (
-                10,
-                4,
-                3,
-            )
-            < self.connection.mysql_version
-            < (10, 5, 2)
-        ):
+        if self.connection.mysql_is_mariadb and (
+            10,
+            4,
+            3,
+        ) < self.connection.mysql_version < (10, 5, 2):
             pass
index 1dfb54ca687d4a9a679d6180f375a931090e265b..9541670e3945df95d264f18e1176f38244c6f8cf 100644 (file)
@@ -4,14 +4,9 @@ if (e123456.get_tk_patchlevel() >= (8, 6, 0, 'final') or
 
 # output
 
-if (
-    e123456.get_tk_patchlevel() >= (8, 6, 0, "final")
-    or (
-        8,
-        5,
-        8,
-    )
-    <= get_tk_patchlevel()
-    < (8, 6)
-):
+if e123456.get_tk_patchlevel() >= (8, 6, 0, "final") or (
+    8,
+    5,
+    8,
+) <= get_tk_patchlevel() < (8, 6):
     pass
index bccf47430a74f622392ad180bd06e4cb76e1cd1e..c0ed699e6a61c2db737fefdcf727ef58941a6b33 100644 (file)
@@ -18,7 +18,4 @@ if True:
                 "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweas "
                 + "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwegqweasdzxcqweasdzxc.",
                 "qweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqweasdzxcqwe",
-            ) % {
-                "reported_username": reported_username,
-                "report_reason": report_reason,
-            }
\ No newline at end of file
+            ) % {"reported_username": reported_username, "report_reason": report_reason}