]> git.madduck.net Git - etc/vim.git/blobdiff - src/black/__init__.py

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:

Treat all trailing commas as pre-existing, as they effectively are
[etc/vim.git] / src / black / __init__.py
index e37caa98a2c00386afd2acd52a4174e7d556d82c..4d4f4b73b916772d490dd16eaa3310157805d78e 100644 (file)
@@ -1627,14 +1627,13 @@ class Line:
 
     def maybe_should_explode(self, closing: Leaf) -> bool:
         """Return True if this line should explode (always be split), that is when:
-        - there's a pre-existing trailing comma here; and
+        - there's a trailing comma here; and
         - it's not a one-tuple.
         """
         if not (
             closing.type in CLOSING_BRACKETS
             and self.leaves
             and self.leaves[-1].type == token.COMMA
-            and not self.leaves[-1].was_checked  # pre-existing
         ):
             return False
 
@@ -2037,13 +2036,20 @@ class LineGenerator(Visitor[Line]):
         yield from self.visit_default(node)
 
     def visit_STRING(self, leaf: Leaf) -> Iterator[Line]:
-        # Check if it's a docstring
-        if prev_siblings_are(
-            leaf.parent, [None, token.NEWLINE, token.INDENT, syms.simple_stmt]
-        ) and is_multiline_string(leaf):
-            prefix = "    " * self.current_line.depth
-            docstring = fix_docstring(leaf.value[3:-3], prefix)
-            leaf.value = leaf.value[0:3] + docstring + leaf.value[-3:]
+        if is_docstring(leaf) and "\\\n" not in leaf.value:
+            # We're ignoring docstrings with backslash newline escapes because changing
+            # indentation of those changes the AST representation of the code.
+            prefix = get_string_prefix(leaf.value)
+            lead_len = len(prefix) + 3
+            tail_len = -3
+            indent = " " * 4 * self.current_line.depth
+            docstring = fix_docstring(leaf.value[lead_len:tail_len], indent)
+            if docstring:
+                if leaf.value[lead_len - 1] == docstring[0]:
+                    docstring = " " + docstring
+                if leaf.value[tail_len + 1] == docstring[-1]:
+                    docstring = docstring + " "
+            leaf.value = leaf.value[0:lead_len] + docstring + leaf.value[tail_len:]
             normalize_string_quotes(leaf)
 
         yield from self.visit_default(leaf)
@@ -2654,7 +2660,7 @@ def transform_line(
             # All splits failed, best effort split with no omits.
             # This mostly happens to multiline strings that are by definition
             # reported as not fitting a single line, as well as lines that contain
-            # pre-existing trailing commas (those have to be exploded).
+            # trailing commas (those have to be exploded).
             yield from right_hand_split(
                 line, line_length=mode.line_length, features=features
             )
@@ -4848,7 +4854,6 @@ def bracket_split_build_line(
 
                     if leaves[i].type != token.COMMA:
                         new_comma = Leaf(token.COMMA, ",")
-                        new_comma.was_checked = True
                         leaves.insert(i + 1, new_comma)
                     break
 
@@ -4944,7 +4949,6 @@ def delimiter_split(line: Line, features: Collection[Feature] = ()) -> Iterator[
             and current_line.leaves[-1].type != STANDALONE_COMMENT
         ):
             new_comma = Leaf(token.COMMA, ",")
-            new_comma.was_checked = True
             current_line.append(new_comma)
         yield current_line
 
@@ -5577,20 +5581,20 @@ def should_split_body_explode(line: Line, opening_bracket: Leaf) -> bool:
     # than one of them (we're excluding the trailing comma and if the delimiter priority
     # is still commas, that means there's more).
     exclude = set()
-    pre_existing_trailing_comma = False
+    trailing_comma = False
     try:
         last_leaf = line.leaves[-1]
         if last_leaf.type == token.COMMA:
-            pre_existing_trailing_comma = not last_leaf.was_checked
+            trailing_comma = True
             exclude.add(id(last_leaf))
         max_priority = line.bracket_tracker.max_delimiter_priority(exclude=exclude)
     except (IndexError, ValueError):
         return False
 
     return max_priority == COMMA_PRIORITY and (
+        trailing_comma
         # always explode imports
-        opening_bracket.parent.type in {syms.atom, syms.import_from}
-        or pre_existing_trailing_comma
+        or opening_bracket.parent.type in {syms.atom, syms.import_from}
     )
 
 
@@ -5720,12 +5724,11 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf
                     line.should_explode
                     and prev
                     and prev.type == token.COMMA
-                    and not prev.was_checked
                     and not is_one_tuple_between(
                         leaf.opening_bracket, leaf, line.leaves
                     )
                 ):
-                    # Never omit bracket pairs with pre-existing trailing commas.
+                    # Never omit bracket pairs with trailing commas.
                     # We need to explode on those.
                     break
 
@@ -5749,10 +5752,9 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf
                 line.should_explode
                 and prev
                 and prev.type == token.COMMA
-                and not prev.was_checked
                 and not is_one_tuple_between(leaf.opening_bracket, leaf, line.leaves)
             ):
-                # Never omit bracket pairs with pre-existing trailing commas.
+                # Never omit bracket pairs with trailing commas.
                 # We need to explode on those.
                 break
 
@@ -6405,11 +6407,7 @@ def can_omit_invisible_parens(
             # unnecessary.
             return True
 
-        if (
-            line.should_explode
-            and penultimate.type == token.COMMA
-            and not penultimate.was_checked
-        ):
+        if line.should_explode and penultimate.type == token.COMMA:
             # The rightmost non-omitted bracket pair is the one we want to explode on.
             return True
 
@@ -6608,6 +6606,26 @@ def patched_main() -> None:
     main()
 
 
+def is_docstring(leaf: Leaf) -> bool:
+    if not is_multiline_string(leaf):
+        # For the purposes of docstring re-indentation, we don't need to do anything
+        # with single-line docstrings.
+        return False
+
+    if prev_siblings_are(
+        leaf.parent, [None, token.NEWLINE, token.INDENT, syms.simple_stmt]
+    ):
+        return True
+
+    # Multiline docstring on the same line as the `def`.
+    if prev_siblings_are(leaf.parent, [syms.parameters, token.COLON, syms.simple_stmt]):
+        # `syms.parameters` is only used in funcdefs and async_funcdefs in the Python
+        # grammar. We're safe to return True without further checks.
+        return True
+
+    return False
+
+
 def fix_docstring(docstring: str, prefix: str) -> str:
     # https://www.python.org/dev/peps/pep-0257/#handling-docstring-indentation
     if not docstring:
@@ -6631,7 +6649,6 @@ def fix_docstring(docstring: str, prefix: str) -> str:
                 trimmed.append(prefix + stripped_line)
             else:
                 trimmed.append("")
-    # Return a single string:
     return "\n".join(trimmed)