From 52fda8b0e9e52e94aae6cb3170c9b1b492a2d8b4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C5=81ukasz=20Langa?= Date: Tue, 24 Apr 2018 11:50:31 -0700 Subject: [PATCH 1/1] Support sticky standalone comments (comments preceding defs, classes, and decorators) Fixes #56 Fixes #154 --- README.md | 11 ++++++----- black.py | 10 ++++++---- tests/comments2.py | 2 -- tests/comments5.py | 40 ++++++++++++++++++++++++++++++++++++++++ tests/comments6.py | 8 -------- tests/empty_lines.py | 10 ++++++++++ tests/fmtonoff.py | 2 -- tests/test_black.py | 8 -------- 8 files changed, 62 insertions(+), 29 deletions(-) delete mode 100644 tests/comments6.py diff --git a/README.md b/README.md index 05bff36..e2f91ef 100644 --- a/README.md +++ b/README.md @@ -230,11 +230,9 @@ are always reformatted to fit minimal space, this whitespace is lost. It will also insert proper spacing before and after function definitions. It's one line before and after inner functions and two lines before and -after module-level functions. *Black* will put those empty lines also -between the function definition and any standalone comments that -immediately precede the given function. If you want to comment on the -entire function, use a docstring or put a leading comment in the function -body. +after module-level functions. *Black* will not put empty lines between +function/class definitions and standalone comments that immediately precede +the given function/class. ### Trailing commas @@ -532,6 +530,9 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md). * fixed comment indentation when a standalone comment closes a block (#16, #32) +* fixed standalone comments receiving extra empty lines if immediately preceding + a class, def, or decorator (#56, #154) + * fixed `--diff` not showing entire path (#130) * fixed parsing of complex expressions after star and double stars in diff --git a/black.py b/black.py index a03b9aa..11386d2 100644 --- a/black.py +++ b/black.py @@ -1040,12 +1040,14 @@ class EmptyLineTracker: # Don't insert empty lines before the first line in the file. return 0, 0 - if self.previous_line and self.previous_line.is_decorator: - # Don't insert empty lines between decorators. + if self.previous_line.is_decorator: return 0, 0 - if is_decorator and self.previous_line and self.previous_line.is_comment: - # Don't insert empty lines between decorator comments. + if ( + self.previous_line.is_comment + and self.previous_line.depth == current_line.depth + and before == 0 + ): return 0, 0 newlines = 2 diff --git a/tests/comments2.py b/tests/comments2.py index 73fff32..44a4711 100644 --- a/tests/comments2.py +++ b/tests/comments2.py @@ -161,8 +161,6 @@ else: # add_compiler(compilers[(7.1, 64)]) # Comment before function. - - def inline_comments_in_brackets_ruin_everything(): if typedargslist: parameters.children = [ diff --git a/tests/comments5.py b/tests/comments5.py index 703922d..d83b6b8 100644 --- a/tests/comments5.py +++ b/tests/comments5.py @@ -27,5 +27,45 @@ try: except OSError: print("problems") +import sys + + +# leading function comment +def wat(): + ... + # trailing function comment + + +# SECTION COMMENT + + +# leading 1 +@deco1 +# leading 2 +@deco2(with_args=True) +# leading 3 +@deco3 +def decorated1(): + ... + + +# leading 1 +@deco1 +# leading 2 +@deco2(with_args=True) +# leading function comment +def decorated1(): + ... + + +# Note: crappy but inevitable. The current design of EmptyLineTracker doesn't +# allow this to work correctly. The user will have to split those lines by +# hand. +some_instruction +# This comment should be split from `some_instruction` by two lines but isn't. +def g(): + ... + + if __name__ == "__main__": main() diff --git a/tests/comments6.py b/tests/comments6.py deleted file mode 100644 index 0565015..0000000 --- a/tests/comments6.py +++ /dev/null @@ -1,8 +0,0 @@ -@property -# TODO: X -@property -# TODO: Y -# TODO: Z -@property -def foo(): - pass diff --git a/tests/empty_lines.py b/tests/empty_lines.py index 0edeb01..5b7ce92 100644 --- a/tests/empty_lines.py +++ b/tests/empty_lines.py @@ -1,3 +1,7 @@ +"""Docstring.""" + + +# leading comment def f(): NO = '' SPACE = ' ' @@ -44,9 +48,11 @@ def f(): syms.dictsetmaker, }: return NO + ############################################################################### # SECTION BECAUSE SECTIONS ############################################################################### + def g(): NO = '' SPACE = ' ' @@ -89,6 +95,10 @@ def g(): # output +"""Docstring.""" + + +# leading comment def f(): NO = "" SPACE = " " diff --git a/tests/fmtonoff.py b/tests/fmtonoff.py index 16c3925..a7b9bc7 100644 --- a/tests/fmtonoff.py +++ b/tests/fmtonoff.py @@ -119,8 +119,6 @@ many_args=[1,2,3] def function_signature_stress_test(number:int,no_annotation=None,text:str='default',* ,debug:bool=False,**kwargs) -> str: return text[number:-1] # fmt: on - - def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""): offset = attr.ib(default=attr.Factory(lambda: _r.uniform(10000, 200000))) assert task._cancel_stack[:len(old_stack)] == old_stack diff --git a/tests/test_black.py b/tests/test_black.py index 9c029df..dd3beed 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -626,14 +626,6 @@ class BlackTestCase(unittest.TestCase): ) self.assertEqual(result.exit_code, 1) - @patch("black.dump_to_file", dump_to_stderr) - def test_comment_in_decorator(self) -> None: - source, expected = read_data("comments6") - actual = fs(source) - self.assertFormatEqual(expected, actual) - black.assert_equivalent(source, actual) - black.assert_stable(source, actual, line_length=ll) - if __name__ == "__main__": unittest.main() -- 2.39.5