diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py index 8f0d159bebd4a..4cae56521beda 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_style.py @@ -1,4 +1,4 @@ -'single' +'single' # this string is treated as a docstring "double" r'r single' r"r double" diff --git a/crates/ruff_python_formatter/src/preview.rs b/crates/ruff_python_formatter/src/preview.rs index 0f7d8d1d323c8..712a7da417088 100644 --- a/crates/ruff_python_formatter/src/preview.rs +++ b/crates/ruff_python_formatter/src/preview.rs @@ -74,3 +74,10 @@ pub(crate) const fn is_hex_codes_in_unicode_sequences_enabled(context: &PyFormat pub(crate) const fn is_multiline_string_handling_enabled(context: &PyFormatContext) -> bool { context.is_preview() } + +/// Returns `true` if the [`multiline_string_handling`](https://github.com/astral-sh/ruff/pull/9725) preview style is enabled. +/// Black does not [`format docstrings`](https://github.com/psf/black/issues/3493) so we keep this +/// preview for compatibility with Black. +pub(crate) const fn is_format_module_docstring_enabled(context: &PyFormatContext) -> bool { + context.is_preview() +} diff --git a/crates/ruff_python_formatter/src/statement/suite.rs b/crates/ruff_python_formatter/src/statement/suite.rs index 59a0030eb46b8..e05a9f6f59017 100644 --- a/crates/ruff_python_formatter/src/statement/suite.rs +++ b/crates/ruff_python_formatter/src/statement/suite.rs @@ -15,7 +15,8 @@ use crate::expression::expr_string_literal::ExprStringLiteralKind; use crate::prelude::*; use crate::preview::{ is_blank_line_after_nested_stub_class_enabled, is_dummy_implementations_enabled, - is_module_docstring_newlines_enabled, is_no_blank_line_before_class_docstring_enabled, + is_format_module_docstring_enabled, is_module_docstring_newlines_enabled, + is_no_blank_line_before_class_docstring_enabled, }; use crate::statement::stmt_expr::FormatStmtExpr; use crate::verbatim::{ @@ -140,7 +141,17 @@ impl FormatRule> for FormatSuite { SuiteChildStatement::Other(first) } } - SuiteKind::TopLevel => SuiteChildStatement::Other(first), + SuiteKind::TopLevel => { + if is_format_module_docstring_enabled(f.context()) { + if let Some(docstring) = DocstringStmt::try_from_statement(first, self.kind) { + SuiteChildStatement::Docstring(docstring) + } else { + SuiteChildStatement::Other(first) + } + } else { + SuiteChildStatement::Other(first) + } + } }; let first_comments = comments.leading_dangling_trailing(first); diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__module_docstring_2.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__module_docstring_2.py.snap deleted file mode 100644 index 29415b12a7af6..0000000000000 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@cases__module_docstring_2.py.snap +++ /dev/null @@ -1,133 +0,0 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/black/cases/module_docstring_2.py ---- -## Input - -```python -"""I am a very helpful module docstring. - -With trailing spaces: -Lorem ipsum dolor sit amet, consectetur adipiscing elit, -sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris -nisi ut aliquip ex ea commodo consequat. -Duis aute irure dolor in reprehenderit in voluptate -velit esse cillum dolore eu fugiat nulla pariatur. -Excepteur sint occaecat cupidatat non proident, -sunt in culpa qui officia deserunt mollit anim id est laborum. -""" - - - - -a = 1 - - -"""Look at me I'm a docstring... - -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -........................................................NOT! -""" - - - - -b = 2 -``` - -## Black Differences - -```diff ---- Black -+++ Ruff -@@ -1,6 +1,6 @@ - """I am a very helpful module docstring. - --With trailing spaces: -+With trailing spaces: - Lorem ipsum dolor sit amet, consectetur adipiscing elit, - sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. - Ut enim ad minim veniam, -``` - -## Ruff Output - -```python -"""I am a very helpful module docstring. - -With trailing spaces: -Lorem ipsum dolor sit amet, consectetur adipiscing elit, -sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris -nisi ut aliquip ex ea commodo consequat. -Duis aute irure dolor in reprehenderit in voluptate -velit esse cillum dolore eu fugiat nulla pariatur. -Excepteur sint occaecat cupidatat non proident, -sunt in culpa qui officia deserunt mollit anim id est laborum. -""" - -a = 1 - - -"""Look at me I'm a docstring... - -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -........................................................NOT! -""" - - -b = 2 -``` - -## Black Output - -```python -"""I am a very helpful module docstring. - -With trailing spaces: -Lorem ipsum dolor sit amet, consectetur adipiscing elit, -sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris -nisi ut aliquip ex ea commodo consequat. -Duis aute irure dolor in reprehenderit in voluptate -velit esse cillum dolore eu fugiat nulla pariatur. -Excepteur sint occaecat cupidatat non proident, -sunt in culpa qui officia deserunt mollit anim id est laborum. -""" - -a = 1 - - -"""Look at me I'm a docstring... - -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -............................................................ -........................................................NOT! -""" - - -b = 2 -``` - - diff --git a/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap index baf143abad3a9..916295345ad7f 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@quote_style.py.snap @@ -4,7 +4,7 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/quote_styl --- ## Input ```python -'single' +'single' # this string is treated as a docstring "double" r'r single' r"r double" @@ -73,7 +73,7 @@ source_type = Python ``` ```python -'single' +'single' # this string is treated as a docstring 'double' r'r single' r'r double' @@ -135,7 +135,8 @@ def docstring_single(): --- Stable +++ Preview @@ -1,4 +1,5 @@ - 'single' +-'single' # this string is treated as a docstring ++"single" # this string is treated as a docstring + 'double' r'r single' @@ -159,7 +160,7 @@ source_type = Python ``` ```python -"single" +"single" # this string is treated as a docstring "double" r"r single" r"r double" @@ -221,7 +222,7 @@ def docstring_single(): --- Stable +++ Preview @@ -1,4 +1,5 @@ - "single" + "single" # this string is treated as a docstring + "double" r"r single" @@ -245,7 +246,7 @@ source_type = Python ``` ```python -'single' +'single' # this string is treated as a docstring "double" r'r single' r"r double" @@ -307,7 +308,8 @@ def docstring_single(): --- Stable +++ Preview @@ -1,4 +1,5 @@ - 'single' +-'single' # this string is treated as a docstring ++"single" # this string is treated as a docstring + "double" r'r single'