diff --git a/CHANGES.md b/CHANGES.md index 244c0182b88..cfe02a477d3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ - Remove unnecessary parentheses from `with` statements (#2926) - Standardise newlines after module-level docstrings (#2996) +- Remove newlines after function docstrings (#1) ### _Blackd_ diff --git a/src/black/linegen.py b/src/black/linegen.py index 2cf9cf3130a..0b927537b0a 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -999,7 +999,6 @@ def maybe_make_parens_invisible_in_atom( def should_split_line(line: Line, opening_bracket: Leaf) -> bool: """Should `line` be immediately split with `delimiter_split()` after RHS?""" - if not (opening_bracket.parent and opening_bracket.value in "[{("): return False @@ -1034,7 +1033,6 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf set is empty, unless the line should explode, in which case bracket pairs until the one that needs to explode are omitted. """ - omit: Set[LeafID] = set() if not line.magic_trailing_comma: yield omit diff --git a/src/black/lines.py b/src/black/lines.py index f43b8281000..2f8f313ad97 100644 --- a/src/black/lines.py +++ b/src/black/lines.py @@ -522,8 +522,19 @@ def _maybe_empty_lines(self, current_line: Line) -> int: and self.previous_lines[-1].is_triple_quoted_string and current_line.depth == self.previous_lines[-1].depth ): + # Single newline after class docstring. return 1 + if ( + self.preview + and len(self.previous_lines) > 1 + and self.previous_lines[-2].is_def + and self.previous_lines[-1].is_triple_quoted_string + and current_line.depth == self.previous_lines[-1].depth + ): + # No newline after function docstring. + return 0 + return before def _maybe_empty_lines_for_class_or_def( diff --git a/src/black/parsing.py b/src/black/parsing.py index 12726567948..20b82a8c589 100644 --- a/src/black/parsing.py +++ b/src/black/parsing.py @@ -193,7 +193,6 @@ def _normalize(lineend: str, value: str) -> str: def stringify_ast(node: Union[ast.AST, ast3.AST], depth: int = 0) -> Iterator[str]: """Simple visitor generating strings to compare ASTs by content.""" - node = fixup_ast_constants(node) yield f"{' ' * depth}{node.__class__.__name__}(" diff --git a/src/black/trans.py b/src/black/trans.py index 01aa80eaaf8..7966216250e 100644 --- a/src/black/trans.py +++ b/src/black/trans.py @@ -73,7 +73,6 @@ def TErr(err_msg: str) -> Err[CannotTransform]: def hug_power_op(line: Line, features: Collection[Feature]) -> Iterator[Line]: """A transformer which normalizes spacing around power operators.""" - # Performance optimization to avoid unnecessary Leaf clones and other ops. for leaf in line.leaves: if leaf.type == token.DOUBLESTAR: diff --git a/tests/data/function_docstring.py b/tests/data/function_docstring.py new file mode 100644 index 00000000000..c3ddfb5f2f7 --- /dev/null +++ b/tests/data/function_docstring.py @@ -0,0 +1,30 @@ +def foo(): + """hello world.""" + + + + print("hello world!") + + +def bar(x: int, y: int) -> int: + """hello world. + + blah blah blah... + """ + + + + return x + y + +# output +def foo(): + """hello world.""" + print("hello world!") + + +def bar(x: int, y: int) -> int: + """hello world. + + blah blah blah... + """ + return x + y diff --git a/tests/test_format.py b/tests/test_format.py index 422e94aa62d..6595c816f10 100644 --- a/tests/test_format.py +++ b/tests/test_format.py @@ -85,6 +85,7 @@ "one_element_subscript", "module_docstring_1", "module_docstring_2", + "function_docstring", ] SOURCES: List[str] = [