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

Treat functions/classes in blocks as if they're nested (GH-2472)
authorRichard Si <63936253+ichard26@users.noreply.github.com>
Wed, 1 Dec 2021 23:05:59 +0000 (18:05 -0500)
committerGitHub <noreply@github.com>
Wed, 1 Dec 2021 23:05:59 +0000 (18:05 -0500)
* Treat functions/classes in blocks as if they're nested

One curveball is that we still want two preceding newlines before blocks
that are probably logically disconnected. In other words:

    if condition:

        def foo():
            return "hi"
                             # <- aside: this is the goal of this commit
    else:

        def foo():
            return "cya"
                             # <- the two newlines spacing here should stay
                             #    since this probably isn't related
    with open("db.json", encoding="utf-8") as f:
        data = f.read()

Unfortunately that means we have to special case specific clause types
instead of just being able to just for a colon leaf. The hack used here
is to check whether we're adding preceding newlines for a standalone or
dependent clause. "Standalone" being a clause that doesn't need another
clause to be valid (eg. if) and vice versa.

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
CHANGES.md
src/black/lines.py
src/black_primer/primer.json
tests/data/function2.py

index 5b648225ad7d679c7caac9caedd98627efcfe45a..590429141740e6d019da698bb2e6b4bba217a338 100644 (file)
@@ -17,6 +17,7 @@
 - Add `flake8-simplify` and `flake8-comprehensions` plugins (#2653)
 - Fix determination of f-string expression spans (#2654)
 - Fix parser error location on invalid syntax in a `match` statement (#2649)
+- Functions and classes in blocks now have more consistent surrounding spacing (#2472)
 
 ## 21.11b1
 
index 63225c0e6d31288bd7c68004e751eb05ca537382..f2bdada008a6519275b97ea4eac4a3bbf3befb26 100644 (file)
@@ -447,11 +447,31 @@ class EmptyLineTracker:
             before = 0
         depth = current_line.depth
         while self.previous_defs and self.previous_defs[-1] >= depth:
-            self.previous_defs.pop()
             if self.is_pyi:
                 before = 0 if depth else 1
             else:
-                before = 1 if depth else 2
+                if depth:
+                    before = 1
+                elif (
+                    not depth
+                    and self.previous_defs[-1]
+                    and current_line.leaves[-1].type == token.COLON
+                    and (
+                        current_line.leaves[0].value
+                        not in ("with", "try", "for", "while", "if", "match")
+                    )
+                ):
+                    # We shouldn't add two newlines between an indented function and
+                    # a dependent non-indented clause. This is to avoid issues with
+                    # conditional function definitions that are technically top-level
+                    # and therefore get two trailing newlines, but look weird and
+                    # inconsistent when they're followed by elif, else, etc. This is
+                    # worse because these functions only get *one* preceding newline
+                    # already.
+                    before = 1
+                else:
+                    before = 2
+            self.previous_defs.pop()
         if current_line.is_decorator or current_line.is_def or current_line.is_class:
             return self._maybe_empty_lines_for_class_or_def(current_line, before)
 
index 2290d1df005048d87ebda72cc789164214d6bc5a..8fe61e889f837efe7c714d3a0699260566fc347e 100644 (file)
     },
     "pyanalyze": {
       "cli_arguments": ["--experimental-string-processing"],
-      "expect_formatting_changes": false,
+      "expect_formatting_changes": true,
       "git_clone_url": "https://github.com/quora/pyanalyze.git",
       "long_checkout": false,
       "py_versions": ["all"]
index cfc259ea7bd7be7e645c606c4e6caed225007ed2..5bb36c26318cbd0b9992b55fd73da3485cf500c7 100644 (file)
@@ -23,6 +23,35 @@ def h():
         pass
     print("Inner defs should breathe a little.")
 
+
+if os.name == "posix":
+    import termios
+    def i_should_be_followed_by_only_one_newline():
+        pass
+elif os.name == "nt":
+    try:
+        import msvcrt
+        def i_should_be_followed_by_only_one_newline():
+            pass
+
+    except ImportError:
+
+        def i_should_be_followed_by_only_one_newline():
+            pass
+
+elif False:
+
+    class IHopeYouAreHavingALovelyDay:
+        def __call__(self):
+            print("i_should_be_followed_by_only_one_newline")
+else:
+
+    def foo():
+        pass
+
+with hmm_but_this_should_get_two_preceding_newlines():
+    pass
+
 # output
 
 def f(
@@ -56,3 +85,37 @@ def h():
         pass
 
     print("Inner defs should breathe a little.")
+
+
+if os.name == "posix":
+    import termios
+
+    def i_should_be_followed_by_only_one_newline():
+        pass
+
+elif os.name == "nt":
+    try:
+        import msvcrt
+
+        def i_should_be_followed_by_only_one_newline():
+            pass
+
+    except ImportError:
+
+        def i_should_be_followed_by_only_one_newline():
+            pass
+
+elif False:
+
+    class IHopeYouAreHavingALovelyDay:
+        def __call__(self):
+            print("i_should_be_followed_by_only_one_newline")
+
+else:
+
+    def foo():
+        pass
+
+
+with hmm_but_this_should_get_two_preceding_newlines():
+    pass