From 7fe19fac5bccc08dbcf21c293ab50f1fcda7716f Mon Sep 17 00:00:00 2001 From: Richard Si <63936253+ichard26@users.noreply.github.com> Date: Wed, 26 Aug 2020 18:17:59 -0400 Subject: [PATCH 1/1] Fix multiline docstring quote normalization The quotes of multiline docstrings are now only normalized when string normalization is off, instead of the string normalization setting being ignored and the quotes being *always* normalized. I had to make a new test case and data file since the current pair for docstrings only worked when there is no formatting difference between the formatting results with string normalization on and off. I needed to add tests for when there *are* differences between the two. So I split test_docstring's test code when string normalization is disabled into a new test case along with a new data file. --- CHANGES.md | 7 + docs/change_log.md | 7 + src/black/__init__.py | 1 - .../data/docstring_no_string_normalization.py | 209 ++++++++++++++++++ tests/test_black.py | 13 +- 5 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 tests/data/docstring_no_string_normalization.py diff --git a/CHANGES.md b/CHANGES.md index 1134177..7352b85 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,12 @@ ## Change Log +### Unreleased + +#### _Black_ + +- `Black` now respects `--skip-string-normalization` when normalizing multiline + docstring quotes (#1637) + ### 20.8b1 #### _Packaging_ diff --git a/docs/change_log.md b/docs/change_log.md index 658414b..b733716 100644 --- a/docs/change_log.md +++ b/docs/change_log.md @@ -2,6 +2,13 @@ ## Change Log +### Unreleased + +#### _Black_ + +- `Black` now respects `--skip-string-normalization` when normalizing multiline + docstring quotes (#1637) + ### 20.8b1 #### _Packaging_ diff --git a/src/black/__init__.py b/src/black/__init__.py index f51a50d..34d8145 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -2049,7 +2049,6 @@ class LineGenerator(Visitor[Line]): if leaf.value[tail_len + 1] == docstring[-1]: docstring = docstring + " " leaf.value = leaf.value[0:lead_len] + docstring + leaf.value[tail_len:] - normalize_string_quotes(leaf) yield from self.visit_default(leaf) diff --git a/tests/data/docstring_no_string_normalization.py b/tests/data/docstring_no_string_normalization.py new file mode 100644 index 0000000..0457fcf --- /dev/null +++ b/tests/data/docstring_no_string_normalization.py @@ -0,0 +1,209 @@ +class ALonelyClass: + ''' + A multiline class docstring. + ''' + def AnEquallyLonelyMethod(self): + ''' + A multiline method docstring''' + pass + + +def one_function(): + '''This is a docstring with a single line of text.''' + pass + + +def shockingly_the_quotes_are_normalized(): + '''This is a multiline docstring. + This is a multiline docstring. + This is a multiline docstring. + ''' + pass + + +def foo(): + """This is a docstring with + some lines of text here + """ + return + + +def baz(): + '''"This" is a string with some + embedded "quotes"''' + return + + +def poit(): + """ + Lorem ipsum dolor sit amet. + + Consectetur adipiscing elit: + - sed do eiusmod tempor incididunt ut labore + - dolore magna aliqua + - enim ad minim veniam + - quis nostrud exercitation ullamco laboris nisi + - aliquip ex ea commodo consequat + """ + pass + + +def under_indent(): + """ + These lines are indented in a way that does not +make sense. + """ + pass + + +def over_indent(): + """ + This has a shallow indent + - But some lines are deeper + - And the closing quote is too deep + """ + pass + + +def single_line(): + """But with a newline after it! + + """ + pass + + +def this(): + r""" + 'hey ho' + """ + + +def that(): + """ "hey yah" """ + + +def and_that(): + """ + "hey yah" """ + + +def and_this(): + ''' + "hey yah"''' + + +def believe_it_or_not_this_is_in_the_py_stdlib(): ''' +"hey yah"''' + + +def shockingly_the_quotes_are_normalized_v2(): + ''' + Docstring Docstring Docstring + ''' + pass + +# output + +class ALonelyClass: + ''' + A multiline class docstring. + ''' + + def AnEquallyLonelyMethod(self): + ''' + A multiline method docstring''' + pass + + +def one_function(): + '''This is a docstring with a single line of text.''' + pass + + +def shockingly_the_quotes_are_normalized(): + '''This is a multiline docstring. + This is a multiline docstring. + This is a multiline docstring. + ''' + pass + + +def foo(): + """This is a docstring with + some lines of text here + """ + return + + +def baz(): + '''"This" is a string with some + embedded "quotes"''' + return + + +def poit(): + """ + Lorem ipsum dolor sit amet. + + Consectetur adipiscing elit: + - sed do eiusmod tempor incididunt ut labore + - dolore magna aliqua + - enim ad minim veniam + - quis nostrud exercitation ullamco laboris nisi + - aliquip ex ea commodo consequat + """ + pass + + +def under_indent(): + """ + These lines are indented in a way that does not + make sense. + """ + pass + + +def over_indent(): + """ + This has a shallow indent + - But some lines are deeper + - And the closing quote is too deep + """ + pass + + +def single_line(): + """But with a newline after it!""" + pass + + +def this(): + r""" + 'hey ho' + """ + + +def that(): + """ "hey yah" """ + + +def and_that(): + """ + "hey yah" """ + + +def and_this(): + ''' + "hey yah"''' + + +def believe_it_or_not_this_is_in_the_py_stdlib(): + ''' + "hey yah"''' + + +def shockingly_the_quotes_are_normalized_v2(): + ''' + Docstring Docstring Docstring + ''' + pass diff --git a/tests/test_black.py b/tests/test_black.py index f5d4e11..629afc5 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -517,11 +517,16 @@ class BlackTestCase(unittest.TestCase): self.assertFormatEqual(expected, actual) black.assert_equivalent(source, actual) black.assert_stable(source, actual, DEFAULT_MODE) + + @patch("black.dump_to_file", dump_to_stderr) + def test_docstring_no_string_normalization(self) -> None: + """Like test_docstring but with string normalization off.""" + source, expected = read_data("docstring_no_string_normalization") mode = replace(DEFAULT_MODE, string_normalization=False) - not_normalized = fs(source, mode=mode) - self.assertFormatEqual(expected, not_normalized) - black.assert_equivalent(source, not_normalized) - black.assert_stable(source, not_normalized, mode=mode) + actual = fs(source, mode=mode) + self.assertFormatEqual(expected, actual) + black.assert_equivalent(source, actual) + black.assert_stable(source, actual, mode) def test_long_strings(self) -> None: """Tests for splitting long strings.""" -- 2.39.5