Skip to content

Commit

Permalink
Stop trimming whitespace in docstrings
Browse files Browse the repository at this point in the history
The PEP 257 algorithm used in psf#1053 results in trimming trailing
whitespace in docstrings -- see psf#1415.

Adjust the algorithm to preserve leading and trailing whitespace; this
reverts the changes in psf#1417.  This diverges from PEP 257, but better
retains the contents of the docstring.

Fixes psf#1452 because we no longer can end up with four trailing quotes.
  • Loading branch information
alexmv committed Jul 31, 2020
1 parent 537ea8d commit 3ef7d4c
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 10 deletions.
22 changes: 15 additions & 7 deletions src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6025,14 +6025,13 @@ def _stringify_ast(

else:
# Constant strings may be indented across newlines, if they are
# docstrings; fold spaces after newlines when comparing. Similarly,
# trailing and leading space may be removed.
# docstrings; fold spaces after newlines when comparing
if (
isinstance(node, ast.Constant)
and field == "value"
and isinstance(value, str)
):
normalized = re.sub(r" *\n[ \t]+", "\n ", value).strip()
normalized = re.sub(r"\n([ \t]+|(?=\n))", "\n ", value)
else:
normalized = value
yield f"{' ' * (depth+2)}{normalized!r}, # {value.__class__.__name__}"
Expand Down Expand Up @@ -6440,13 +6439,22 @@ def fix_docstring(docstring: str, prefix: str) -> str:
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxsize:
trimmed = [lines[0]]
if indent == sys.maxsize:
# We got no indent information from the later lines; they were
# all just whitespace. Preserve the number of newlines.
for _ in lines[1:-1]:
trimmed.append("")
if len(lines) > 1:
trimmed.append(prefix)
else:
last_line_idx = len(lines) - 2
for i, line in enumerate(lines[1:]):
stripped_line = line[indent:].rstrip()
if stripped_line or i == last_line_idx:
trimmed.append(prefix + stripped_line)
if stripped_line:
trimmed.append(prefix + line[indent:])
elif i == last_line_idx:
trimmed.append(prefix)
else:
trimmed.append("")
# Return a single string:
Expand Down
72 changes: 69 additions & 3 deletions tests/data/docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,42 @@ def single_line():
"""
pass


def containing_quotes():
"""No quotes here
"quotes here" """
pass


def containing_unbalanced_quotes():
"""No quotes here
quote here" """
pass


def entirely_space():
"""
"""
pass


def just_quote():
""" " """
pass


def escaped_already():
"""
foo\""""
pass

# output

class MyClass:
"""Multiline
""" Multiline
class docstring
"""

Expand All @@ -88,7 +120,7 @@ def method(self):


def foo():
"""This is a docstring with
"""This is a docstring with
some lines of text here
"""
return
Expand Down Expand Up @@ -146,5 +178,39 @@ def over_indent():


def single_line():
"""But with a newline after it!"""
"""But with a newline after it!
"""
pass


def containing_quotes():
"""No quotes here
"quotes here" """
pass


def containing_unbalanced_quotes():
"""No quotes here
quote here" """
pass


def entirely_space():
"""
"""
pass


def just_quote():
""" " """
pass


def escaped_already():
"""
foo\""""
pass

0 comments on commit 3ef7d4c

Please sign in to comment.