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

Enforce a blank line after a nested class in stubs (#3564)
authorWMOkiishi <w.muneo.o@gmail.com>
Sat, 18 Mar 2023 21:04:13 +0000 (15:04 -0600)
committerGitHub <noreply@github.com>
Sat, 18 Mar 2023 21:04:13 +0000 (14:04 -0700)
CHANGES.md
src/black/lines.py
src/black/mode.py
tests/data/miscellaneous/nested_class_stub.pyi [new file with mode: 0644]
tests/test_format.py

index e2f21cf8f8a41905bcd7e40eb4cf4c23dbf07612..029d0bcbd3f4edcbb46de9c61a84c1e81a00bd60 100644 (file)
@@ -23,6 +23,8 @@
   compared to their non-async version. (#3609)
 - `with` statements that contain two context managers will be consistently wrapped in
   parentheses (#3589)
   compared to their non-async version. (#3609)
 - `with` statements that contain two context managers will be consistently wrapped in
   parentheses (#3589)
+- For stubs, enforce one blank line after a nested class with a body other than just
+  `...` (#3564)
 
 ### Configuration
 
 
 ### Configuration
 
index 66bba14b357166eb984dcba459689aaf3eb87142..b2bdcc441b48c80c7f1d8d279bbb11cf364fafbf 100644 (file)
@@ -521,7 +521,7 @@ class EmptyLineTracker:
     mode: Mode
     previous_line: Optional[Line] = None
     previous_block: Optional[LinesBlock] = None
     mode: Mode
     previous_line: Optional[Line] = None
     previous_block: Optional[LinesBlock] = None
-    previous_defs: List[int] = field(default_factory=list)
+    previous_defs: List[Line] = field(default_factory=list)
     semantic_leading_comment: Optional[LinesBlock] = None
 
     def maybe_empty_lines(self, current_line: Line) -> LinesBlock:
     semantic_leading_comment: Optional[LinesBlock] = None
 
     def maybe_empty_lines(self, current_line: Line) -> LinesBlock:
@@ -577,12 +577,18 @@ class EmptyLineTracker:
         else:
             before = 0
         depth = current_line.depth
         else:
             before = 0
         depth = current_line.depth
-        while self.previous_defs and self.previous_defs[-1] >= depth:
+        while self.previous_defs and self.previous_defs[-1].depth >= depth:
             if self.mode.is_pyi:
                 assert self.previous_line is not None
                 if depth and not current_line.is_def and self.previous_line.is_def:
                     # Empty lines between attributes and methods should be preserved.
                     before = min(1, before)
             if self.mode.is_pyi:
                 assert self.previous_line is not None
                 if depth and not current_line.is_def and self.previous_line.is_def:
                     # Empty lines between attributes and methods should be preserved.
                     before = min(1, before)
+                elif (
+                    Preview.blank_line_after_nested_stub_class in self.mode
+                    and self.previous_defs[-1].is_class
+                    and not self.previous_defs[-1].is_stub_class
+                ):
+                    before = 1
                 elif depth:
                     before = 0
                 else:
                 elif depth:
                     before = 0
                 else:
@@ -637,7 +643,7 @@ class EmptyLineTracker:
         self, current_line: Line, before: int
     ) -> Tuple[int, int]:
         if not current_line.is_decorator:
         self, current_line: Line, before: int
     ) -> Tuple[int, int]:
         if not current_line.is_decorator:
-            self.previous_defs.append(current_line.depth)
+            self.previous_defs.append(current_line)
         if self.previous_line is None:
             # Don't insert empty lines before the first line in the file.
             return 0, 0
         if self.previous_line is None:
             # Don't insert empty lines before the first line in the file.
             return 0, 0
index 6af041791937a0f6e29ff77f82bded006f5bbda1..0511676ce5394dcf8c616c924f5d774bb397320f 100644 (file)
@@ -154,6 +154,7 @@ class Preview(Enum):
     """Individual preview style features."""
 
     add_trailing_comma_consistently = auto()
     """Individual preview style features."""
 
     add_trailing_comma_consistently = auto()
+    blank_line_after_nested_stub_class = auto()
     hex_codes_in_unicode_sequences = auto()
     improved_async_statements_handling = auto()
     multiline_string_handling = auto()
     hex_codes_in_unicode_sequences = auto()
     improved_async_statements_handling = auto()
     multiline_string_handling = auto()
diff --git a/tests/data/miscellaneous/nested_class_stub.pyi b/tests/data/miscellaneous/nested_class_stub.pyi
new file mode 100644 (file)
index 0000000..daf281b
--- /dev/null
@@ -0,0 +1,16 @@
+class Outer:
+    class InnerStub: ...
+    outer_attr_after_inner_stub: int
+    class Inner:
+        inner_attr: int
+    outer_attr: int
+
+# output
+class Outer:
+    class InnerStub: ...
+    outer_attr_after_inner_stub: int
+
+    class Inner:
+        inner_attr: int
+
+    outer_attr: int
index ab849aac9a3fccfd003801718aa36f7b9bb098c1..3a6cbc9e2e936a144b2dc0b478eebffb1ec2a51f 100644 (file)
@@ -186,6 +186,12 @@ def test_stub() -> None:
     assert_format(source, expected, mode)
 
 
     assert_format(source, expected, mode)
 
 
+def test_nested_class_stub() -> None:
+    mode = replace(DEFAULT_MODE, is_pyi=True, preview=True)
+    source, expected = read_data("miscellaneous", "nested_class_stub.pyi")
+    assert_format(source, expected, mode)
+
+
 def test_power_op_newline() -> None:
     # requires line_length=0
     source, expected = read_data("miscellaneous", "power_op_newline")
 def test_power_op_newline() -> None:
     # requires line_length=0
     source, expected = read_data("miscellaneous", "power_op_newline")