From 9b1698fcb7ac2e85585e672ee40ddb761a47ec05 Mon Sep 17 00:00:00 2001 From: konstin Date: Fri, 27 Oct 2023 12:03:20 +0200 Subject: [PATCH] Change strategy to manual comment formatting --- .../resources/test/fixtures/ruff/docstring.py | 14 ++++ .../src/comments/placement.rs | 32 +-------- .../src/statement/suite.rs | 34 +++++++-- ...mpatibility@simple_cases__fmtonoff.py.snap | 10 ++- .../tests/snapshots/format@docstring.py.snap | 70 +++++++++++++++++++ 5 files changed, 123 insertions(+), 37 deletions(-) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py index 31c5949c78db7..adefe843b9715 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py @@ -118,6 +118,20 @@ def __init__(self): pass +class CommentAfterDocstring4: + """Browse module classes and functions in IDLE.""" + + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring5: + """Browse module classes and functions in IDLE.""" + # This class is also the base class for pathbrowser.PathBrowser. + + class TabbedIndent: def tabbed_indent(self): """check for correct tabbed formatting diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index 1ea71654fe460..09b19c6539028 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -1,8 +1,9 @@ use std::cmp::Ordering; use ruff_python_ast::whitespace::indentation; -use ruff_python_ast::{self as ast, Comprehension, Expr, MatchCase, ModModule, Parameters}; -use ruff_python_ast::{AnyNodeRef, Constant}; +use ruff_python_ast::{ + self as ast, AnyNodeRef, Comprehension, Expr, MatchCase, ModModule, Parameters, +}; use ruff_python_trivia::{ find_only_token_in_range, indentation_at_offset, BackwardsTokenizer, CommentRanges, SimpleToken, SimpleTokenKind, SimpleTokenizer, @@ -548,33 +549,6 @@ fn handle_own_line_comment_between_statements<'a>( return CommentPlacement::Default(comment); } - // Comments after docstrings need a newline between the docstring and the comment, so we attach - // it as leading on the first statement after the docstring. - // (https://github.com/astral-sh/ruff/issues/7948) - // ```python - // class ModuleBrowser: - // """Browse module classes and functions in IDLE.""" - // # ^ Insert a newline above here - // - // def __init__(self, master, path, *, _htest=False, _utest=False): - // pass - // ``` - if let AnyNodeRef::StmtExpr(preceding_expr) = preceding { - // We can't use `is_docstring_stmt` here because there is no `AnyNodeRef` to `&Stmt` - // conversion - if is_first_statement_in_body(preceding, comment.enclosing_node()) - && matches!( - preceding_expr.value.as_ref(), - Expr::Constant(ast::ExprConstant { - value: Constant::Str { .. }, - .. - }) - ) - { - return CommentPlacement::leading(following, comment); - } - } - // If the comment is directly attached to the following statement; make it a leading // comment: // ```python diff --git a/crates/ruff_python_formatter/src/statement/suite.rs b/crates/ruff_python_formatter/src/statement/suite.rs index ea48cdf4088c7..843241cd11594 100644 --- a/crates/ruff_python_formatter/src/statement/suite.rs +++ b/crates/ruff_python_formatter/src/statement/suite.rs @@ -547,9 +547,11 @@ impl<'a> DocstringStmt<'a> { }; if let Expr::Constant(ExprConstant { value, .. }) = value.as_ref() { - if !value.is_implicit_concatenated() { - return Some(DocstringStmt(stmt)); - } + return match value { + Constant::Str(value) if !value.implicit_concatenated => Some(DocstringStmt(stmt)), + Constant::Bytes(value) if !value.implicit_concatenated => Some(DocstringStmt(stmt)), + _ => None, + }; } None @@ -581,9 +583,31 @@ impl Format> for DocstringStmt<'_> { constant .format() .with_options(ExprConstantLayout::String(StringLayout::DocString)), - trailing_comments(node_comments.trailing), ] - ) + )?; + + // Comments after docstrings need a newline between the docstring and the comment, so we attach + // it as leading on the first statement after the docstring. + // (https://github.com/astral-sh/ruff/issues/7948) + // ```python + // class ModuleBrowser: + // """Browse module classes and functions in IDLE.""" + // # ^ Insert a newline above here + // + // def __init__(self, master, path, *, _htest=False, _utest=False): + // pass + // ``` + if let Some(own_line) = node_comments + .trailing + .iter() + .find(|comment| comment.line_position().is_own_line()) + { + if lines_before(own_line.start(), f.context().source()) < 2 { + empty_line().fmt(f)?; + } + } + + trailing_comments(node_comments.trailing).fmt(f) } } } diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap index ce417c728b56b..ef41670ec0231 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap @@ -225,8 +225,11 @@ d={'a':1, # fmt: on goes + here, andhere, -@@ -122,8 +123,10 @@ +@@ -120,10 +121,13 @@ + + The comments between will be formatted. This is a known limitation. """ ++ # fmt: off - # hey, that won't work @@ -237,7 +240,7 @@ d={'a':1, # fmt: on pass -@@ -138,7 +141,7 @@ +@@ -138,7 +142,7 @@ now . considers . multiple . fmt . directives . within . one . prefix # fmt: on # fmt: off @@ -246,7 +249,7 @@ d={'a':1, # fmt: on -@@ -178,14 +181,18 @@ +@@ -178,14 +182,18 @@ $ """, # fmt: off @@ -395,6 +398,7 @@ def off_and_on_without_data(): The comments between will be formatted. This is a known limitation. """ + # fmt: off diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap index 949e770714a4a..673d54f7a5c5a 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap @@ -124,6 +124,20 @@ class CommentAfterDocstring3: pass +class CommentAfterDocstring4: + """Browse module classes and functions in IDLE.""" + + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring5: + """Browse module classes and functions in IDLE.""" + # This class is also the base class for pathbrowser.PathBrowser. + + class TabbedIndent: def tabbed_indent(self): """check for correct tabbed formatting @@ -264,6 +278,20 @@ class CommentAfterDocstring3: pass +class CommentAfterDocstring4: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring5: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + class TabbedIndent: def tabbed_indent(self): """check for correct tabbed formatting @@ -404,6 +432,20 @@ class CommentAfterDocstring3: pass +class CommentAfterDocstring4: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring5: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + class TabbedIndent: def tabbed_indent(self): """check for correct tabbed formatting @@ -544,6 +586,20 @@ class CommentAfterDocstring3: pass +class CommentAfterDocstring4: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring5: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + class TabbedIndent: def tabbed_indent(self): """check for correct tabbed formatting @@ -684,6 +740,20 @@ class CommentAfterDocstring3: pass +class CommentAfterDocstring4: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + def __init__(self): + pass + + +class CommentAfterDocstring5: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + class TabbedIndent: def tabbed_indent(self): """check for correct tabbed formatting