Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actually disable docstring prefix normalization with -S + fix instability #3168

Merged
merged 4 commits into from Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -19,6 +19,8 @@

- Single-character closing docstring quotes are no longer moved to their own line as
this is invalid. This was a bug introduced in version 22.6.0. (#3166)
- `--skip-string-normalization` / `-S` now prevents docstring prefixes from being
normalized as expected (#3168)

### _Blackd_

Expand Down
19 changes: 18 additions & 1 deletion src/black/linegen.py
Expand Up @@ -293,7 +293,24 @@ def visit_STRING(self, leaf: Leaf) -> Iterator[Line]:
if is_docstring(leaf) and "\\\n" not in leaf.value:
# We're ignoring docstrings with backslash newline escapes because changing
# indentation of those changes the AST representation of the code.
docstring = normalize_string_prefix(leaf.value)
if Preview.normalize_docstring_quotes_and_prefixes_properly in self.mode:
# There was a bug where --skip-string-normalization wouldn't stop us
# from normalize docstring prefixes. To maintain stability, we can only
JelleZijlstra marked this conversation as resolved.
Show resolved Hide resolved
# address this buggy behaviour while the preview style is enabled.
if self.mode.string_normalization:
docstring = normalize_string_prefix(leaf.value)
# visit_default() does handle string normalization for us, but
# since this method acts differently depending on quote style (ex.
# see padding logic below), there's a possibility for unstable
# formatting as visit_default() is called *after*. To avoid a
# situation where this function formats a docstring differently on
# the second pass, normalize it early.
docstring = normalize_string_quotes(docstring)
else:
docstring = leaf.value
else:
# ... otherwise, we'll keep the buggy behaviour >.<
docstring = normalize_string_prefix(leaf.value)
prefix = get_string_prefix(docstring)
docstring = docstring[len(prefix) :] # Remove the prefix
quote_char = docstring[0]
Expand Down
7 changes: 4 additions & 3 deletions src/black/mode.py
Expand Up @@ -145,12 +145,13 @@ def supports_feature(target_versions: Set[TargetVersion], feature: Feature) -> b
class Preview(Enum):
"""Individual preview style features."""

string_processing = auto()
remove_redundant_parens = auto()
one_element_subscript = auto()
annotation_parens = auto()
long_docstring_quotes_on_newline = auto()
normalize_docstring_quotes_and_prefixes_properly = auto()
one_element_subscript = auto()
remove_block_trailing_newline = auto()
remove_redundant_parens = auto()
string_processing = auto()


class Deprecated(UserWarning):
Expand Down
@@ -0,0 +1,10 @@
def do_not_touch_this_prefix():
R"""There was a bug where docstring prefixes would be normalized even with -S."""


def do_not_touch_this_prefix2():
F'There was a bug where docstring prefixes would be normalized even with -S.'


def do_not_touch_this_prefix3():
uR'''There was a bug where docstring prefixes would be normalized even with -S.'''
14 changes: 14 additions & 0 deletions tests/data/simple_cases/docstring.py
Expand Up @@ -209,6 +209,13 @@ def multiline_docstring_at_line_limit():
second line----------------------------------------------------------------------"""


def stable_quote_normalization_with_immediate_inner_single_quote(self):
''''<text here>

<text here, since without another non-empty line black is stable>
'''


# output

class MyClass:
Expand Down Expand Up @@ -417,3 +424,10 @@ def multiline_docstring_at_line_limit():
"""first line-----------------------------------------------------------------------

second line----------------------------------------------------------------------"""


def stable_quote_normalization_with_immediate_inner_single_quote(self):
"""'<text here>

<text here, since without another non-empty line black is stable>
"""
12 changes: 12 additions & 0 deletions tests/test_format.py
Expand Up @@ -139,6 +139,18 @@ def test_docstring_no_string_normalization() -> None:
assert_format(source, expected, mode)


def test_preview_docstring_no_string_normalization() -> None:
"""
Like test_docstring but with string normalization off *and* the preview style
enabled.
"""
source, expected = read_data(
"miscellaneous", "docstring_preview_no_string_normalization"
)
mode = replace(DEFAULT_MODE, string_normalization=False, preview=True)
assert_format(source, expected, mode)


def test_long_strings_flag_disabled() -> None:
"""Tests for turning off the string processing logic."""
source, expected = read_data("miscellaneous", "long_strings_flag_disabled")
Expand Down