Skip to content

Commit

Permalink
Be more careful with docstrings ending with quotes + whitespace
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 and fixes in psf#1417.  Removing
trailing whitespace may result in four quotes in a row:

    def foo():
        """"Some content
        and more "here" """
        pass

When closing the docstring, escape any trailing quote characters that
it matches, if they are not already escaped.

Fixes psf#1452.
  • Loading branch information
alexmv committed May 22, 2020
1 parent ff6bbd5 commit 860bcf8
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2083,6 +2083,15 @@ def visit_STRING(self, leaf: Leaf) -> Iterator[Line]:
) and is_multiline_string(leaf):
prefix = " " * self.current_line.depth
docstring = fix_docstring(leaf.value[3:-3], prefix)
quote_char = leaf.value[0]
if len(docstring) > 0 and docstring[-1] == quote_char:
# This may have trimmed trailing whitespace, which may
# have produced four quotes in a row. Escape the last
# quote -- if it isn't already, by being preceded by
# an odd number of backslashes
docstring = re.compile(rf"(([^\\]|^)(\\\\)*){quote_char}$").sub(
rf"\1\\{quote_char}", docstring
)
leaf.value = leaf.value[0:3] + docstring + leaf.value[-3:]
normalize_string_quotes(leaf)

Expand Down
62 changes: 62 additions & 0 deletions tests/data/docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,38 @@ 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:
Expand Down Expand Up @@ -148,3 +180,33 @@ def over_indent():
def single_line():
"""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 860bcf8

Please sign in to comment.