-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Fix normalize_string_prefix not lowercasing uppercase T t-string prefix #5185
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
base: main
Are you sure you want to change the base?
Changes from all commits
ef488e1
657390e
5a89055
ba4ec87
c35bed0
8ea4c12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,11 +6,15 @@ | |
| import sys | ||
| from functools import lru_cache | ||
| from re import Match, Pattern | ||
| from typing import Final | ||
| from typing import TYPE_CHECKING, Final | ||
|
|
||
| from black._width_table import WIDTH_TABLE | ||
| from blib2to3.pytree import Leaf | ||
|
|
||
| if TYPE_CHECKING: | ||
| from black.mode import Mode | ||
|
|
||
|
|
||
| STRING_PREFIX_CHARS: Final = "fturbFTURB" # All possible string prefix characters. | ||
| STRING_PREFIX_RE: Final = re.compile( | ||
| r"^([" + STRING_PREFIX_CHARS + r"]*)(.*)$", re.DOTALL | ||
|
|
@@ -142,7 +146,7 @@ def assert_is_leaf_string(string: str) -> None: | |
| ), f"{set(string[:quote_idx])} is NOT a subset of {set(STRING_PREFIX_CHARS)}." | ||
|
|
||
|
|
||
| def normalize_string_prefix(s: str) -> str: | ||
| def normalize_string_prefix(s: str, mode: "Mode | None" = None) -> str: | ||
| """Make all string prefixes lowercase.""" | ||
| match = STRING_PREFIX_RE.match(s) | ||
| assert match is not None, f"failed to match string {s!r}" | ||
|
|
@@ -153,13 +157,21 @@ def normalize_string_prefix(s: str) -> str: | |
| .replace("U", "") | ||
| .replace("u", "") | ||
| ) | ||
| if mode is None or _is_preview_tstring_normalization(mode): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you inline the |
||
| new_prefix = new_prefix.replace("T", "t") | ||
|
|
||
| # Python syntax guarantees max 2 prefixes and that one of them is "r" | ||
| if len(new_prefix) == 2 and new_prefix[0].lower() != "r": | ||
| new_prefix = new_prefix[::-1] | ||
| return f"{new_prefix}{match.group(2)}" | ||
|
|
||
|
|
||
| def _is_preview_tstring_normalization(mode: "Mode") -> bool: | ||
| from black.mode import Preview | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this inline import? Why can't we just import |
||
|
|
||
| return Preview.normalize_tstring_prefix in mode | ||
|
|
||
|
|
||
| # Re(gex) does actually cache patterns internally but this still improves | ||
| # performance on a long list literal of strings by 5-9% since lru_cache's | ||
| # caching overhead is much lower. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # flags: --preview --minimum-version=3.14 | ||
|
|
||
| # Uppercase T prefix is normalized to lowercase t in preview style | ||
| x = T"bar {1 + 1}" | ||
| x = T'bar {1 + 1}' | ||
| rT'\{{\}}' | ||
|
|
||
| # output | ||
|
|
||
| # Uppercase T prefix is normalized to lowercase t in preview style | ||
| x = t"bar {1 + 1}" | ||
| x = t"bar {1 + 1}" | ||
| rt"\{{\}}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer for mode to be required, just so we don't accidentally forget it anywhere. Black's public API isn't considered stable, so it's not a breaking change.