ruff/crates/ruff_python_formatter/tests/snapshots/format@docstring.py.snap
Andrew Gallant d9845a2628
format doctests in docstrings (#8811)
## Summary

This PR adds opt-in support for formatting doctests in docstrings. This
reflects initial support and it is intended to add support for Markdown
and reStructuredText Python code blocks in the future. But I believe
this PR lays the groundwork, and future additions for Markdown and reST
should be less costly to add.

It's strongly recommended to review this PR commit-by-commit. The last
few commits in particular implement the bulk of the work here and
represent the denser portions.

Some things worth mentioning:

* The formatter is itself not perfect, and it is possible for it to
produce invalid Python code. Because of this, reformatted code snippets
are checked for Python validity. If they aren't valid, then we
(unfortunately silently) bail on formatting that code snippet.
* There are a couple places where it would be nice to at least warn the
user that doctest formatting failed, but it wasn't clear to me what the
best way to do that is.
* I haven't yet run this in anger on a real world code base. I think
that should happen before merging.

Closes #7146 

## Test Plan

* [x] Pass the local test suite.
* [x] Scrutinize ecosystem changes.
* [x] Run this formatter on extant code and scrutinize the results.
(e.g., CPython, numpy.)
2023-11-27 11:14:55 -05:00

834 lines
16 KiB
Text

---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring.py
---
## Input
```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
"""
```
## Outputs
### Output 1
```
indent-style = space
line-width = 88
indent-width = 4
quote-style = Double
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
"""
```
### Output 2
```
indent-style = space
line-width = 88
indent-width = 2
quote-style = Double
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
"""
```
### Output 3
```
indent-style = tab
line-width = 88
indent-width = 8
quote-style = Double
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
"""
```
### Output 4
```
indent-style = tab
line-width = 88
indent-width = 4
quote-style = Double
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
"""
```