From 4fae912ec93d0795ad4a829a5cfb150e1f8f96ed Mon Sep 17 00:00:00 2001 From: felix-hilden Date: Thu, 3 Jun 2021 23:47:28 +0300 Subject: [PATCH] Change rule to "r" last --- docs/the_black_code_style/current_style.md | 8 ++++---- src/black/strings.py | 14 +++++++------- src/blib2to3/pgen2/tokenize.py | 2 +- tests/data/string_prefixes.py | 4 ++-- tests/data/string_quotes.py | 4 ++-- tests/test_black.py | 6 +++--- tests/test_ipynb.py | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/the_black_code_style/current_style.md b/docs/the_black_code_style/current_style.md index f1cc6196f6d..45e6189930f 100644 --- a/docs/the_black_code_style/current_style.md +++ b/docs/the_black_code_style/current_style.md @@ -235,10 +235,10 @@ escapes than before. _Black_ also standardizes string prefixes. Prefix characters are made lowercase with the exception of [capital "R" prefixes](#rstrings-and-rstrings), and in the case of multiple -characters "r" is put first as in spoken language: "raw f-string". On top of that, if -your code is already Python 3.6+ only or it's using the `unicode_literals` future -import, _Black_ will remove `u` from the string prefix as it is meaningless in those -scenarios. +characters "r" is put last as the common prefix and as required in Python 2. On top of +that, if your code is already Python 3.6+ only or it's using the `unicode_literals` +future import, _Black_ will remove `u` from the string prefix as it is meaningless in +those scenarios. The main reason to standardize on a single form of quotes is aesthetics. Having one kind of quotes everywhere reduces reader distraction. It will also enable a future version of diff --git a/src/black/strings.py b/src/black/strings.py index 9d0e2eb8430..43fd326656d 100644 --- a/src/black/strings.py +++ b/src/black/strings.py @@ -151,7 +151,7 @@ def normalize_string_prefix(s: str) -> str: ) # Python syntax guarantees max 2 prefixes and that one of them is "r" - if len(new_prefix) == 2 and "r" != new_prefix[0].lower(): + if len(new_prefix) == 2 and "r" == new_prefix[0].lower(): new_prefix = new_prefix[::-1] return f"{new_prefix}{match.group(2)}" @@ -188,9 +188,9 @@ def normalize_string_quotes(s: str) -> str: return s # There's an internal error prefix = s[:first_quote_pos] - unescaped_new_quote = _cached_compile(rf"(([^\\]|^)(\\\\)*){new_quote}") - escaped_new_quote = _cached_compile(rf"([^\\]|^)\\((?:\\\\)*){new_quote}") - escaped_orig_quote = _cached_compile(rf"([^\\]|^)\\((?:\\\\)*){orig_quote}") + unescaped_new_quote = _cached_compile(fr"(([^\\]|^)(\\\\)*){new_quote}") + escaped_new_quote = _cached_compile(fr"([^\\]|^)\\((?:\\\\)*){new_quote}") + escaped_orig_quote = _cached_compile(fr"([^\\]|^)\\((?:\\\\)*){orig_quote}") body = s[first_quote_pos + len(orig_quote) : -len(orig_quote)] if "r" in prefix.casefold(): if unescaped_new_quote.search(body): @@ -202,13 +202,13 @@ def normalize_string_quotes(s: str) -> str: new_body = body else: # remove unnecessary escapes - new_body = sub_twice(escaped_new_quote, rf"\1\2{new_quote}", body) + new_body = sub_twice(escaped_new_quote, fr"\1\2{new_quote}", body) if body != new_body: # Consider the string without unnecessary escapes as the original body = new_body s = f"{prefix}{orig_quote}{body}{orig_quote}" - new_body = sub_twice(escaped_orig_quote, rf"\1\2{orig_quote}", new_body) - new_body = sub_twice(unescaped_new_quote, rf"\1\\{new_quote}", new_body) + new_body = sub_twice(escaped_orig_quote, fr"\1\2{orig_quote}", new_body) + new_body = sub_twice(unescaped_new_quote, fr"\1\\{new_quote}", new_body) if "f" in prefix.casefold(): matches = re.findall( r""" diff --git a/src/blib2to3/pgen2/tokenize.py b/src/blib2to3/pgen2/tokenize.py index 257dbef4a19..a7e17df1e8f 100644 --- a/src/blib2to3/pgen2/tokenize.py +++ b/src/blib2to3/pgen2/tokenize.py @@ -293,7 +293,7 @@ def compat(self, token: Tuple[int, Text], iterable: Iterable[TokenInfo]) -> None cookie_re = re.compile(r"^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)", re.ASCII) -blank_re = re.compile(rb"^[ \t\f]*(?:[#\r\n]|$)", re.ASCII) +blank_re = re.compile(br"^[ \t\f]*(?:[#\r\n]|$)", re.ASCII) def _get_normal_name(orig_enc: str) -> str: diff --git a/tests/data/string_prefixes.py b/tests/data/string_prefixes.py index f86da696e15..1ff3e59678f 100644 --- a/tests/data/string_prefixes.py +++ b/tests/data/string_prefixes.py @@ -31,8 +31,8 @@ def docstring_multiline(): ("", "") (r"", R"") -(rf"", rf"", Rf"", Rf"", rf"", rf"", Rf"", Rf"") -(rb"", rb"", Rb"", Rb"", rb"", rb"", Rb"", Rb"") +(fr"", fr"", fR"", fR"", fr"", fr"", fR"", fR"") +(br"", br"", bR"", bR"", br"", br"", bR"", bR"") def docstring_singleline(): diff --git a/tests/data/string_quotes.py b/tests/data/string_quotes.py index 3384241f4ad..8b620360044 100644 --- a/tests/data/string_quotes.py +++ b/tests/data/string_quotes.py @@ -23,7 +23,7 @@ r'Date d\'expiration:(.*)' r'Tricky "quote' r'Not-so-tricky \"quote' -rf'{yay}' +fr'{yay}' '\n\ The \"quick\"\n\ brown fox\n\ @@ -83,7 +83,7 @@ r"Date d\'expiration:(.*)" r'Tricky "quote' r"Not-so-tricky \"quote" -rf"{yay}" +fr"{yay}" "\nThe \"quick\"\nbrown fox\njumps over\nthe 'lazy' dog.\n" re.compile(r'[\\"]') "x = ''; y = \"\"" diff --git a/tests/test_black.py b/tests/test_black.py index 91d10581f6f..44be324eccf 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -290,7 +290,7 @@ def test_expression_diff(self) -> None: expected, _ = read_data("expression.diff") tmp_file = Path(black.dump_to_file(source)) diff_header = re.compile( - rf"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d " + fr"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d " r"\d\d:\d\d:\d\d\.\d\d\d\d\d\d \+\d\d\d\d" ) try: @@ -355,7 +355,7 @@ def test_skip_magic_trailing_comma(self) -> None: expected, _ = read_data("expression_skip_magic_trailing_comma.diff") tmp_file = Path(black.dump_to_file(source)) diff_header = re.compile( - rf"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d " + fr"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d " r"\d\d:\d\d:\d\d\.\d\d\d\d\d\d \+\d\d\d\d" ) try: @@ -1424,7 +1424,7 @@ def test_bpo_2142_workaround(self) -> None: expected, _ = read_data("missing_final_newline.diff") tmp_file = Path(black.dump_to_file(source, ensure_final_newline=False)) diff_header = re.compile( - rf"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d " + fr"{re.escape(str(tmp_file))}\t\d\d\d\d-\d\d-\d\d " r"\d\d:\d\d:\d\d\.\d\d\d\d\d\d \+\d\d\d\d" ) try: diff --git a/tests/test_ipynb.py b/tests/test_ipynb.py index fe8d67a7777..79228be1926 100644 --- a/tests/test_ipynb.py +++ b/tests/test_ipynb.py @@ -341,7 +341,7 @@ def test_empty_string() -> None: def test_unparseable_notebook() -> None: path = DATA_DIR / "notebook_which_cant_be_parsed.ipynb" - msg = rf"File '{re.escape(str(path))}' cannot be parsed as valid Jupyter notebook\." + msg = fr"File '{re.escape(str(path))}' cannot be parsed as valid Jupyter notebook\." with pytest.raises(ValueError, match=msg): format_file_in_place(path, fast=True, mode=JUPYTER_MODE)