From 9993bb0cf34144d852679f953c61ce5c798cff65 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 6 Dec 2023 15:01:34 +0800 Subject: [PATCH] Enforce double quotes for all docstrings --- .../test/fixtures/ruff/docstring.options.json | 3 + .../resources/test/fixtures/ruff/docstring.py | 5 + .../src/expression/string/mod.rs | 7 +- .../tests/snapshots/format@docstring.py.snap | 198 ++++++++++++++++++ 4 files changed, 209 insertions(+), 4 deletions(-) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json index 28553e727b70fa..e1a76386a0556c 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.options.json @@ -14,5 +14,8 @@ { "indent_style": "tab", "indent_width": 4 + }, + { + "quote_style": "single" } ] 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 d7d4d9b119b173..98a5a730f44f68 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py @@ -150,3 +150,8 @@ def tabbed_indent(self): Normal indented line - autor """ + + +def single_quoted(): + ' content\ ' + return diff --git a/crates/ruff_python_formatter/src/expression/string/mod.rs b/crates/ruff_python_formatter/src/expression/string/mod.rs index 5a7a6a1b4677b3..c7e896daf2c907 100644 --- a/crates/ruff_python_formatter/src/expression/string/mod.rs +++ b/crates/ruff_python_formatter/src/expression/string/mod.rs @@ -213,7 +213,8 @@ impl<'a> Format> for FormatString<'a> { let normalized = string_part.normalize( Quoting::CanChange, &locator, - f.options().quote_style(), + // Per PEP 8 and PEP 257, always prefer double quotes for docstrings + QuoteStyle::Double, parent_docstring_quote_style, ); docstring::format(&normalized, f) @@ -323,9 +324,7 @@ impl StringPart { configured_style: QuoteStyle, parent_docstring_quote_style: Option, ) -> NormalizedString<'a> { - // Per PEP 8 and PEP 257, always prefer double quotes for docstrings - // and triple-quoted strings. (We assume docstrings are always - // triple-quoted.) + // Per PEP 8, always prefer double quotes for triple-quoted strings. let preferred_style = if self.quotes.triple { // ... unless we're formatting a code snippet inside a docstring, // then we specifically want to invert our quote style to avoid 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 bac8a446b18a14..84e737e97a6c66 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap @@ -156,6 +156,11 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + ' content\ ' + return ``` ## Outputs @@ -324,6 +329,11 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return ``` @@ -492,6 +502,11 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return ``` @@ -660,6 +675,11 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return ``` @@ -828,6 +848,184 @@ class TabbedIndent: Normal indented line - autor """ + + +def single_quoted(): + "content\ " + return +``` + + +### Output 5 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Single +line-ending = LineFeed +magic-trailing-comma = Respect +docstring-code = Disabled +preview = Disabled +``` + +```python +def single_line_backslashes1(): + """content\ """ + return + + +def single_line_backslashes2(): + """content\\""" + return + + +def single_line_backslashes3(): + """content\\\ """ + return + + +def multiline_backslashes1(): + """This is a docstring with + some lines of text\ """ + return + + +def multiline_backslashes2(): + """This is a docstring with + some lines of text\\""" + return + + +def multiline_backslashes3(): + """This is a docstring with + some lines of text\\\ """ + return + + +def multiple_negatively_indented_docstring_lines(): + """a + b + c + d + e + """ + + +def overindentend_docstring(): + """a + over-indented + """ + + +def comment_before_docstring(): + # don't lose this function comment ... + """Does nothing. + + But it has comments + """ # ... neither lose this function comment + + +class CommentBeforeDocstring: + # don't lose this class comment ... + """Empty class. + + But it has comments + """ # ... neither lose this class comment + + +class IndentMeSome: + def doc_string_without_linebreak_after_colon(self): + """This is somewhat strange + a + b + We format this a is the docstring had started properly indented on the next + line if the target indentation. This may we incorrect since source and target + indentation can be incorrect, but this is also an edge case. + """ + + +class IgnoreImplicitlyConcatenatedStrings: + """""" '' + + +def docstring_that_ends_with_quote_and_a_line_break1(): + """ + he said "the news of my death have been greatly exaggerated" + """ + + +def docstring_that_ends_with_quote_and_a_line_break2(): + """he said "the news of my death have been greatly exaggerated" """ + + +def docstring_that_ends_with_quote_and_a_line_break3(): + """he said "the news of my death have been greatly exaggerated" """ + + +class ByteDocstring: + b""" has leading whitespace""" + first_statement = 1 + + +class CommentAfterDocstring1: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + def __init__(self): + pass + + +class CommentAfterDocstring2: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + + def __init__(self): + pass + + +class CommentAfterDocstring3: + """Browse module classes and functions in IDLE.""" + + # This class is also the base class for pathbrowser.PathBrowser. + 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. + + +def f(): + """Browse module classes and functions in IDLE.""" + # ^ Do not insert a newline above here + + pass + + +class TabbedIndent: + def tabbed_indent(self): + """check for correct tabbed formatting + ^^^^^^^^^^ + Normal indented line + - autor + """ + + +def single_quoted(): + "content\ " + return ```