diff --git a/crates/ruff_python_formatter/src/expression/string/docstring.rs b/crates/ruff_python_formatter/src/expression/string/docstring.rs index 8f1f335218..21057e4645 100644 --- a/crates/ruff_python_formatter/src/expression/string/docstring.rs +++ b/crates/ruff_python_formatter/src/expression/string/docstring.rs @@ -457,6 +457,10 @@ impl<'ast, 'buf, 'fmt, 'src> DocstringLinePrinter<'ast, 'buf, 'fmt, 'src> { #[derive(Clone, Debug)] struct DocstringLine<'src> { /// The actual text of the line, not including the line terminator. + /// + /// In practice, this line is borrowed when it corresponds to an original + /// unformatted line in a docstring, and owned when it corresponds to a + /// reformatted line (e.g., from a code snippet) in a docstring. line: Cow<'src, str>, /// The offset into the source document which this line corresponds to. offset: TextSize, @@ -561,8 +565,10 @@ enum CodeExampleKind { /// found as part of the Python standard library: /// https://docs.python.org/3/library/doctest.html. /// - /// (You'll likely need to read the regex matching used internally by the + /// (You'll likely need to read the [regex matching] used internally by the /// doctest module to determine more precisely how it works.) + /// + /// [regex matching]: https://github.com/python/cpython/blob/0ff6368519ed7542ad8b443de01108690102420a/Lib/doctest.py#L611-L622 Doctest(CodeExampleDoctest), } @@ -631,11 +637,11 @@ enum CodeExampleAddAction<'src> { /// /// This is guaranteed to be non-empty. code: Vec>, - /// When set, the line is considered not part of any code example - /// and should be formatted as if the `Ignore` action were returned. + /// When set, the line is considered not part of any code example and + /// should be formatted as if the [`Print`] action were returned. /// Otherwise, if there is no line, then either one does not exist /// or it is part of another code example and should be treated as a - /// `Kept` action. + /// [`Kept`] action. original: Option>, }, } diff --git a/crates/ruff_python_formatter/tests/normalizer.rs b/crates/ruff_python_formatter/tests/normalizer.rs index d6f6454ed3..d0f2ba0b9c 100644 --- a/crates/ruff_python_formatter/tests/normalizer.rs +++ b/crates/ruff_python_formatter/tests/normalizer.rs @@ -63,12 +63,14 @@ impl Transformer for Normalizer { static STRIP_CODE_SNIPPETS: Lazy = Lazy::new(|| { Regex::new( r#"(?mx) - # strip doctest PS1 prompt lines - ^\s*>>>\s.*(\n|$) - | - # strip doctest PS2 prompt lines - # Also handles the case of an empty ... line. - ^\s*\.\.\.((\n|$)|\s.*(\n|$)) + ( + # strip doctest PS1 prompt lines + ^\s*>>>\s.*(\n|$) + | + # strip doctest PS2 prompt lines + # Also handles the case of an empty ... line. + ^\s*\.\.\.((\n|$)|\s.*(\n|$)) + )+ "#, ) .unwrap() @@ -78,7 +80,10 @@ impl Transformer for Normalizer { // snippet, since code snippets may be completely reformatted if // they are Python code. string_literal.value = STRIP_CODE_SNIPPETS - .replace_all(&string_literal.value, "") + .replace_all( + &string_literal.value, + "\n", + ) .into_owned(); // Normalize a string by (2) stripping any leading and trailing space from each // line, and (3) removing any blank lines from the start and end of the string.