Support sticky standalone comments (comments preceding defs, classes, and decorators)
Fixes #56 Fixes #154
This commit is contained in:
parent
29e97d1d4a
commit
52fda8b0e9
11
README.md
11
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 will also insert proper spacing before and after function definitions.
|
||||||
It's one line before and after inner functions and two lines before and
|
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
|
after module-level functions. *Black* will not put empty lines between
|
||||||
between the function definition and any standalone comments that
|
function/class definitions and standalone comments that immediately precede
|
||||||
immediately precede the given function. If you want to comment on the
|
the given function/class.
|
||||||
entire function, use a docstring or put a leading comment in the function
|
|
||||||
body.
|
|
||||||
|
|
||||||
|
|
||||||
### Trailing commas
|
### 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 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 `--diff` not showing entire path (#130)
|
||||||
|
|
||||||
* fixed parsing of complex expressions after star and double stars in
|
* fixed parsing of complex expressions after star and double stars in
|
||||||
|
10
black.py
10
black.py
@ -1040,12 +1040,14 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]:
|
|||||||
# Don't insert empty lines before the first line in the file.
|
# Don't insert empty lines before the first line in the file.
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
||||||
if self.previous_line and self.previous_line.is_decorator:
|
if self.previous_line.is_decorator:
|
||||||
# Don't insert empty lines between decorators.
|
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
||||||
if is_decorator and self.previous_line and self.previous_line.is_comment:
|
if (
|
||||||
# Don't insert empty lines between decorator comments.
|
self.previous_line.is_comment
|
||||||
|
and self.previous_line.depth == current_line.depth
|
||||||
|
and before == 0
|
||||||
|
):
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
||||||
newlines = 2
|
newlines = 2
|
||||||
|
@ -161,8 +161,6 @@ def inline_comments_in_brackets_ruin_everything():
|
|||||||
# add_compiler(compilers[(7.1, 64)])
|
# add_compiler(compilers[(7.1, 64)])
|
||||||
|
|
||||||
# Comment before function.
|
# Comment before function.
|
||||||
|
|
||||||
|
|
||||||
def inline_comments_in_brackets_ruin_everything():
|
def inline_comments_in_brackets_ruin_everything():
|
||||||
if typedargslist:
|
if typedargslist:
|
||||||
parameters.children = [
|
parameters.children = [
|
||||||
|
@ -27,5 +27,45 @@
|
|||||||
except OSError:
|
except OSError:
|
||||||
print("problems")
|
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__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
@property
|
|
||||||
# TODO: X
|
|
||||||
@property
|
|
||||||
# TODO: Y
|
|
||||||
# TODO: Z
|
|
||||||
@property
|
|
||||||
def foo():
|
|
||||||
pass
|
|
@ -1,3 +1,7 @@
|
|||||||
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
# leading comment
|
||||||
def f():
|
def f():
|
||||||
NO = ''
|
NO = ''
|
||||||
SPACE = ' '
|
SPACE = ' '
|
||||||
@ -44,9 +48,11 @@ def f():
|
|||||||
syms.dictsetmaker,
|
syms.dictsetmaker,
|
||||||
}:
|
}:
|
||||||
return NO
|
return NO
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# SECTION BECAUSE SECTIONS
|
# SECTION BECAUSE SECTIONS
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
def g():
|
def g():
|
||||||
NO = ''
|
NO = ''
|
||||||
SPACE = ' '
|
SPACE = ' '
|
||||||
@ -89,6 +95,10 @@ def g():
|
|||||||
# output
|
# output
|
||||||
|
|
||||||
|
|
||||||
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
# leading comment
|
||||||
def f():
|
def f():
|
||||||
NO = ""
|
NO = ""
|
||||||
SPACE = " "
|
SPACE = " "
|
||||||
|
@ -119,8 +119,6 @@ async def coroutine(arg, exec=False):
|
|||||||
def function_signature_stress_test(number:int,no_annotation=None,text:str='default',* ,debug:bool=False,**kwargs) -> str:
|
def function_signature_stress_test(number:int,no_annotation=None,text:str='default',* ,debug:bool=False,**kwargs) -> str:
|
||||||
return text[number:-1]
|
return text[number:-1]
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
def spaces(a=1, b=(), c=[], d={}, e=True, f=-1, g=1 if False else 2, h="", i=r""):
|
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)))
|
offset = attr.ib(default=attr.Factory(lambda: _r.uniform(10000, 200000)))
|
||||||
assert task._cancel_stack[:len(old_stack)] == old_stack
|
assert task._cancel_stack[:len(old_stack)] == old_stack
|
||||||
|
@ -626,14 +626,6 @@ def test_check_diff_use_together(self) -> None:
|
|||||||
)
|
)
|
||||||
self.assertEqual(result.exit_code, 1)
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user