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

Do not wrap implicitly concatenated strings used as func args in parens (#3640)
authorYilei "Dolee" Yang <yileiyang@google.com>
Fri, 28 Apr 2023 18:10:01 +0000 (11:10 -0700)
committerGitHub <noreply@github.com>
Fri, 28 Apr 2023 18:10:01 +0000 (11:10 -0700)
CHANGES.md
src/black/__init__.py
src/black/mode.py
src/black/parsing.py
src/black/trans.py
tests/data/preview/cantfit.py
tests/data/preview/long_strings.py
tests/data/preview/long_strings__regression.py
tests/test_black.py

index 7c76bca4f6aabd55a4df78a26ac2cd55ff2ac0e3..c7ecc396214b3841623e65c50a1991159c468eac 100644 (file)
@@ -14,6 +14,9 @@
 
 <!-- Changes that affect Black's preview style -->
 
+- Implicitly concatenated strings used as function args are no longer wrapped inside
+  parentheses (#3640)
+
 ### Configuration
 
 <!-- Changes to how Black can be configured -->
index 4ebf28821c39ca339b05f372de2695246f6fcc99..871e9a0d7c8cf9e56477469ca7929346a3511a0e 100644 (file)
@@ -503,10 +503,8 @@ def main(  # noqa: C901
             user_level_config = str(find_user_pyproject_toml())
             if config == user_level_config:
                 out(
-                    (
-                        "Using configuration from user-level config at "
-                        f"'{user_level_config}'."
-                    ),
+                    "Using configuration from user-level config at "
+                    f"'{user_level_config}'.",
                     fg="blue",
                 )
             elif config_source in (
index 0511676ce5394dcf8c616c924f5d774bb397320f..3e37a588e522d5c594c916f874244951526f759b 100644 (file)
@@ -188,10 +188,8 @@ class Mode:
     def __post_init__(self) -> None:
         if self.experimental_string_processing:
             warn(
-                (
-                    "`experimental string processing` has been included in `preview`"
-                    " and deprecated. Use `preview` instead."
-                ),
+                "`experimental string processing` has been included in `preview`"
+                " and deprecated. Use `preview` instead.",
                 Deprecated,
             )
 
index eaa3c367e54876982a4b3836ea999fb0ccb5cb65..70ed99c15494e9fa438309d8b0e1d99626b5080a 100644 (file)
@@ -29,11 +29,9 @@ try:
 except ImportError:
     if sys.version_info < (3, 8) and not _IS_PYPY:
         print(
-            (
-                "The typed_ast package is required but not installed.\n"
-                "You can upgrade to Python 3.8+ or install typed_ast with\n"
-                "`python3 -m pip install typed-ast`."
-            ),
+            "The typed_ast package is required but not installed.\n"
+            "You can upgrade to Python 3.8+ or install typed_ast with\n"
+            "`python3 -m pip install typed-ast`.",
             file=sys.stderr,
         )
         sys.exit(1)
index 95695f32b14573138f1ccfdd02d2ce1dc3cb9d6b..1e28ed0656e2c637ecf65ccbdece7c40ef952c75 100644 (file)
@@ -1186,19 +1186,33 @@ class BaseStringSplitter(StringTransformer):
         if LL[0].type != token.STRING:
             return None
 
-        # If the string is surrounded by commas (or is the first/last child)...
-        prev_sibling = LL[0].prev_sibling
-        next_sibling = LL[0].next_sibling
-        if not prev_sibling and not next_sibling and parent_type(LL[0]) == syms.atom:
-            # If it's an atom string, we need to check the parent atom's siblings.
-            parent = LL[0].parent
-            assert parent is not None  # For type checkers.
-            prev_sibling = parent.prev_sibling
-            next_sibling = parent.next_sibling
-        if (not prev_sibling or prev_sibling.type == token.COMMA) and (
-            not next_sibling or next_sibling.type == token.COMMA
+        matching_nodes = [
+            syms.listmaker,
+            syms.dictsetmaker,
+            syms.testlist_gexp,
+        ]
+        # If the string is an immediate child of a list/set/tuple literal...
+        if (
+            parent_type(LL[0]) in matching_nodes
+            or parent_type(LL[0].parent) in matching_nodes
         ):
-            return 0
+            # And the string is surrounded by commas (or is the first/last child)...
+            prev_sibling = LL[0].prev_sibling
+            next_sibling = LL[0].next_sibling
+            if (
+                not prev_sibling
+                and not next_sibling
+                and parent_type(LL[0]) == syms.atom
+            ):
+                # If it's an atom string, we need to check the parent atom's siblings.
+                parent = LL[0].parent
+                assert parent is not None  # For type checkers.
+                prev_sibling = parent.prev_sibling
+                next_sibling = parent.next_sibling
+            if (not prev_sibling or prev_sibling.type == token.COMMA) and (
+                not next_sibling or next_sibling.type == token.COMMA
+            ):
+                return 0
 
         return None
 
@@ -1811,8 +1825,9 @@ class StringParenWrapper(BaseStringSplitter, CustomSplitMapMixin):
         * The line is an lambda expression and the value is a string.
             OR
         * The line starts with an "atom" string that prefers to be wrapped in
-        parens. It's preferred to be wrapped when the string is surrounded by
-        commas (or is the first/last child).
+        parens. It's preferred to be wrapped when it's is an immediate child of
+        a list/set/tuple literal, AND the string is surrounded by commas (or is
+        the first/last child).
 
     Transformations:
         The chosen string is wrapped in parentheses and then split at the LPAR.
index cade382e30d8cff6de35c8dbfd0f1ceeba43c006..0849374f776ebbefc13f0332dd55aaeb0e690feb 100644 (file)
@@ -79,14 +79,10 @@ normal_name = (
 )
 # long arguments
 normal_name = normal_function_name(
-    (
-        "but with super long string arguments that on their own exceed the line limit"
-        " so there's no way it can ever fit"
-    ),
-    (
-        "eggs with spam and eggs and spam with eggs with spam and eggs and spam with"
-        " eggs with spam and eggs and spam with eggs"
-    ),
+    "but with super long string arguments that on their own exceed the line limit so"
+    " there's no way it can ever fit",
+    "eggs with spam and eggs and spam with eggs with spam and eggs and spam with eggs"
+    " with spam and eggs and spam with eggs",
     this_is_a_ridiculously_long_name_and_nobody_in_their_right_mind_would_use_one_like_it=0,
 )
 string_variable_name = "a string that is waaaaaaaayyyyyyyy too long, even in parens, there's nothing you can do"  # noqa
index c68da3a8632c35b5af961f31d2729dcec0acbadf..059148729d57ed784eb3dc015426475a8882ad1b 100644 (file)
@@ -323,10 +323,8 @@ x += (
 y = "Short string"
 
 print(
-    (
-        "This is a really long string inside of a print statement with extra arguments"
-        " attached at the end of it."
-    ),
+    "This is a really long string inside of a print statement with extra arguments"
+    " attached at the end of it.",
     x,
     y,
     z,
@@ -501,15 +499,13 @@ bad_split3 = (
 )
 
 bad_split_func1(
-    (
-        "But what should happen when code has already "
-        "been formatted but in the wrong way? Like "
-        "with a space at the end instead of the "
-        "beginning. Or what about when it is split too "
-        "soon? In the case of a split that is too "
-        "short, black will try to honer the custom "
-        "split."
-    ),
+    "But what should happen when code has already "
+    "been formatted but in the wrong way? Like "
+    "with a space at the end instead of the "
+    "beginning. Or what about when it is split too "
+    "soon? In the case of a split that is too "
+    "short, black will try to honer the custom "
+    "split.",
     xxx,
     yyy,
     zzz,
@@ -612,11 +608,9 @@ comment_string = (  # This comment gets thrown to the top.
 )
 
 arg_comment_string = print(
-    (  # This comment gets thrown to the top.
-        "Long lines with inline comments which are apart of (and not the only member"
-        " of) an argument list should have their comments appended to the reformatted"
-        " string's enclosing left parentheses."
-    ),
+    "Long lines with inline comments which are apart of (and not the only member of) an"
+    " argument list should have their comments appended to the reformatted string's"
+    " enclosing left parentheses.",  # This comment gets thrown to the top.
     "Arg #2",
     "Arg #3",
     "Arg #4",
@@ -676,31 +670,23 @@ return (
 )
 
 func_with_bad_comma(
-    (
-        "This is a really long string argument to a function that has a trailing comma"
-        " which should NOT be there."
-    ),
+    "This is a really long string argument to a function that has a trailing comma"
+    " which should NOT be there.",
 )
 
 func_with_bad_comma(
-    (  # comment after comma
-        "This is a really long string argument to a function that has a trailing comma"
-        " which should NOT be there."
-    ),
+    "This is a really long string argument to a function that has a trailing comma"
+    " which should NOT be there.",  # comment after comma
 )
 
 func_with_bad_comma(
-    (
-        "This is a really long string argument to a function that has a trailing comma"
-        " which should NOT be there."
-    ),
+    "This is a really long string argument to a function that has a trailing comma"
+    " which should NOT be there.",
 )
 
 func_with_bad_comma(
-    (  # comment after comma
-        "This is a really long string argument to a function that has a trailing comma"
-        " which should NOT be there."
-    ),
+    "This is a really long string argument to a function that has a trailing comma"
+    " which should NOT be there.",  # comment after comma
 )
 
 func_with_bad_parens_that_wont_fit_in_one_line(
index eead8c204a9fc1ce89dcc680c0bc40df5b064e94..5f0646e6029bcab434b9e51749c7f514c843cca3 100644 (file)
@@ -715,11 +715,9 @@ class A:
     def foo():
         some_func_call(
             "xxxxxxxxxx",
-            (
-                "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x "
-                '"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; '
-                "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" "
-            ),
+            "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x "
+            '"xxxx xxxxxxx xxxxxx xxxx; xxxx xxxxxx_xxxxx xxxxxx xxxx; '
+            "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ",
             None,
             ("xxxxxxxxxxx",),
         ),
@@ -728,11 +726,9 @@ class A:
 class A:
     def foo():
         some_func_call(
-            (
-                "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x "
-                "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; "
-                "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" "
-            ),
+            "xx {xxxxxxxxxxx}/xxxxxxxxxxx.xxx xxxx.xxx && xxxxxx -x "
+            "xxxx, ('xxxxxxx xxxxxx xxxx, xxxx') xxxxxx_xxxxx xxxxxx xxxx; "
+            "xxxx.xxxx_xxxxxx(['xxxx.xxx'], xxxx.xxxxxxx().xxxxxxxxxx)\" ",
             None,
             ("xxxxxxxxxxx",),
         ),
@@ -850,10 +846,8 @@ some_commented_string = (
 )
 
 lpar_and_rpar_have_comments = func_call(  # LPAR Comment
-    (  # Comma Comment
-        "Long really ridiculous type of string that shouldn't really even exist at all."
-        " I mean commmme onnn!!!"
-    ),
+    "Long really ridiculous type of string that shouldn't really even exist at all. I"
+    " mean commmme onnn!!!",  # Comma Comment
 )  # RPAR Comment
 
 cmd_fstring = (
index e5e1777771548f0ca3c6c6de59f926e83a99ef07..00de5b745e7842af4a3e95254b3d4e63afe08450 100644 (file)
@@ -567,10 +567,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(err_lines[-1], "error: cannot format e1: boom")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "1 file reformatted, 2 files left unchanged, 1 file failed to"
-                    " reformat."
-                ),
+                "1 file reformatted, 2 files left unchanged, 1 file failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.done(Path("f3"), black.Changed.YES)
@@ -579,10 +577,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(out_lines[-1], "reformatted f3")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 1 file failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 1 file failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.failed(Path("e2"), "boom")
@@ -591,10 +587,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(err_lines[-1], "error: cannot format e2: boom")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.path_ignored(Path("wat"), "no match")
@@ -603,10 +597,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(out_lines[-1], "wat ignored: no match")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.done(Path("f4"), black.Changed.NO)
@@ -615,28 +607,22 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(out_lines[-1], "f4 already well formatted, good job.")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 3 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 3 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.check = True
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files would be reformatted, 3 files would be left unchanged, 2"
-                    " files would fail to reformat."
-                ),
+                "2 files would be reformatted, 3 files would be left unchanged, 2"
+                " files would fail to reformat.",
             )
             report.check = False
             report.diff = True
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files would be reformatted, 3 files would be left unchanged, 2"
-                    " files would fail to reformat."
-                ),
+                "2 files would be reformatted, 3 files would be left unchanged, 2"
+                " files would fail to reformat.",
             )
 
     def test_report_quiet(self) -> None:
@@ -678,10 +664,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(err_lines[-1], "error: cannot format e1: boom")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "1 file reformatted, 2 files left unchanged, 1 file failed to"
-                    " reformat."
-                ),
+                "1 file reformatted, 2 files left unchanged, 1 file failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.done(Path("f3"), black.Changed.YES)
@@ -689,10 +673,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(len(err_lines), 1)
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 1 file failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 1 file failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.failed(Path("e2"), "boom")
@@ -701,10 +683,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(err_lines[-1], "error: cannot format e2: boom")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.path_ignored(Path("wat"), "no match")
@@ -712,10 +692,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(len(err_lines), 2)
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.done(Path("f4"), black.Changed.NO)
@@ -723,28 +701,22 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(len(err_lines), 2)
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 3 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 3 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.check = True
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files would be reformatted, 3 files would be left unchanged, 2"
-                    " files would fail to reformat."
-                ),
+                "2 files would be reformatted, 3 files would be left unchanged, 2"
+                " files would fail to reformat.",
             )
             report.check = False
             report.diff = True
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files would be reformatted, 3 files would be left unchanged, 2"
-                    " files would fail to reformat."
-                ),
+                "2 files would be reformatted, 3 files would be left unchanged, 2"
+                " files would fail to reformat.",
             )
 
     def test_report_normal(self) -> None:
@@ -788,10 +760,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(err_lines[-1], "error: cannot format e1: boom")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "1 file reformatted, 2 files left unchanged, 1 file failed to"
-                    " reformat."
-                ),
+                "1 file reformatted, 2 files left unchanged, 1 file failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.done(Path("f3"), black.Changed.YES)
@@ -800,10 +770,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(out_lines[-1], "reformatted f3")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 1 file failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 1 file failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.failed(Path("e2"), "boom")
@@ -812,10 +780,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(err_lines[-1], "error: cannot format e2: boom")
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.path_ignored(Path("wat"), "no match")
@@ -823,10 +789,8 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(len(err_lines), 2)
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 2 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 2 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.done(Path("f4"), black.Changed.NO)
@@ -834,28 +798,22 @@ class BlackTestCase(BlackBaseTestCase):
             self.assertEqual(len(err_lines), 2)
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files reformatted, 3 files left unchanged, 2 files failed to"
-                    " reformat."
-                ),
+                "2 files reformatted, 3 files left unchanged, 2 files failed to"
+                " reformat.",
             )
             self.assertEqual(report.return_code, 123)
             report.check = True
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files would be reformatted, 3 files would be left unchanged, 2"
-                    " files would fail to reformat."
-                ),
+                "2 files would be reformatted, 3 files would be left unchanged, 2"
+                " files would fail to reformat.",
             )
             report.check = False
             report.diff = True
             self.assertEqual(
                 unstyle(str(report)),
-                (
-                    "2 files would be reformatted, 3 files would be left unchanged, 2"
-                    " files would fail to reformat."
-                ),
+                "2 files would be reformatted, 3 files would be left unchanged, 2"
+                " files would fail to reformat.",
             )
 
     def test_lib2to3_parse(self) -> None: