From cf2282d6e848f1e1ad5e804c7e18abc0acc4c9c2 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 26 Apr 2021 07:54:14 -0700 Subject: [PATCH 1/3] Fix crash on docstrings ending with "\ " Fixes #2136 --- CHANGES.md | 2 ++ src/black/__init__.py | 8 +++++++- tests/data/docstring.py | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index aa08396e491..769f01ea13e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,8 @@ #### _Black_ +- Fix crash on docstrings ending with "\ ". (#2142) + - Reflect the `--skip-magic-trailing-comma` and `--experimental-string-processing` flags in the name of the cache file. Without this fix, changes in these flags would not take effect if the cache had already been populated. (#2131) diff --git a/src/black/__init__.py b/src/black/__init__.py index 00d3729c835..f9bd6a3414b 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -2179,7 +2179,13 @@ def visit_STRING(self, leaf: Leaf) -> Iterator[Line]: indent = " " * 4 * self.current_line.depth docstring = fix_docstring(docstring, indent) else: - docstring = docstring.strip() + new_docstring = docstring.strip() + # If the docstring ended with "\ ", stripping away the space + # will be a syntax error. Just put the trailing space back. + if new_docstring.endswith("\\"): + docstring = docstring.lstrip() + else: + docstring = new_docstring if docstring: # Add some padding if the docstring starts / ends with a quote mark. diff --git a/tests/data/docstring.py b/tests/data/docstring.py index 9e1c2441e0e..fade592127a 100644 --- a/tests/data/docstring.py +++ b/tests/data/docstring.py @@ -158,6 +158,10 @@ def docstring_with_inline_tabs_and_tab_indentation(): """ pass + +def backslash_space(): + """\ """ + # output class MyClass: @@ -316,3 +320,7 @@ def docstring_with_inline_tabs_and_tab_indentation(): line ends with some tabs """ pass + + +def backslash_space(): + """\ """ From 03889695d68df8323c8df372b3fbd52237dd2f50 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 26 Apr 2021 08:56:36 -0700 Subject: [PATCH 2/3] add a test case --- tests/data/docstring.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/data/docstring.py b/tests/data/docstring.py index fade592127a..8bf5b9aedbd 100644 --- a/tests/data/docstring.py +++ b/tests/data/docstring.py @@ -162,6 +162,12 @@ def docstring_with_inline_tabs_and_tab_indentation(): def backslash_space(): """\ """ + +def multiline_backslash(): + ''' + hey\there\ + \ ''' + # output class MyClass: @@ -324,3 +330,9 @@ def docstring_with_inline_tabs_and_tab_indentation(): def backslash_space(): """\ """ + + +def multiline_backslash(): + """ + hey\there\ + \ """ From f5a5921a627491ad389c686b97afae4f08a52b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Mon, 26 Apr 2021 19:13:41 +0200 Subject: [PATCH 3/3] Also handle multiline string docstrings --- src/black/__init__.py | 16 ++++++++-------- tests/data/docstring.py | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/black/__init__.py b/src/black/__init__.py index f9bd6a3414b..7701a35e9d5 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -2179,20 +2179,20 @@ def visit_STRING(self, leaf: Leaf) -> Iterator[Line]: indent = " " * 4 * self.current_line.depth docstring = fix_docstring(docstring, indent) else: - new_docstring = docstring.strip() - # If the docstring ended with "\ ", stripping away the space - # will be a syntax error. Just put the trailing space back. - if new_docstring.endswith("\\"): - docstring = docstring.lstrip() - else: - docstring = new_docstring + docstring = docstring.strip() if docstring: # Add some padding if the docstring starts / ends with a quote mark. if docstring[0] == quote_char: docstring = " " + docstring if docstring[-1] == quote_char: - docstring = docstring + " " + docstring += " " + if docstring[-1] == "\\": + backslash_count = len(docstring) - len(docstring.rstrip("\\")) + if backslash_count % 2: + # Odd number of tailing backslashes, add some padding to + # avoid escaping the closing string quote. + docstring += " " else: # Add some padding if the docstring is empty. docstring = " " diff --git a/tests/data/docstring.py b/tests/data/docstring.py index 8bf5b9aedbd..ee6d0c051d7 100644 --- a/tests/data/docstring.py +++ b/tests/data/docstring.py @@ -163,11 +163,17 @@ def backslash_space(): """\ """ -def multiline_backslash(): +def multiline_backslash_1(): ''' hey\there\ \ ''' + +def multiline_backslash_2(): + ''' + hey there \ ''' + + # output class MyClass: @@ -332,7 +338,12 @@ def backslash_space(): """\ """ -def multiline_backslash(): +def multiline_backslash_1(): """ hey\there\ \ """ + + +def multiline_backslash_2(): + """ + hey there \ """