From: Zsolt Dollenstein Date: Wed, 4 Apr 2018 20:20:46 +0000 (+0100) Subject: Handle backslashes in raw strings while normalizing (#105) X-Git-Url: https://git.madduck.net/etc/vim.git/commitdiff_plain/51b3b2624d4b1e4608eb9addd7d292cc5174a047?ds=inline;hp=f8e9544c930a1469bee8b3f131687e2cae52e59b Handle backslashes in raw strings while normalizing (#105) In raw strings, a single backslash means a literal backslash. It is also used to escape quotes if it precedes them. This means it is impossible to change the quote type for strings that contain an unescaped version of the other quote type. Fixes #100 --- diff --git a/black.py b/black.py index 01390b3..4995b53 100644 --- a/black.py +++ b/black.py @@ -1917,10 +1917,20 @@ def normalize_string_quotes(leaf: Leaf) -> None: if first_quote_pos == -1: return # There's an internal error + prefix = leaf.value[:first_quote_pos] body = leaf.value[first_quote_pos + len(orig_quote):-len(orig_quote)] - new_body = body.replace(f"\\{orig_quote}", orig_quote).replace( - new_quote, f"\\{new_quote}" - ) + if "r" in prefix.casefold(): + if body.count(new_quote) != body.count(f"\\{new_quote}"): + # There's at least one unescaped new_quote in this raw string + # so converting is impossible + return + + # Do not introduce or remove backslashes in raw strings + new_body = body + else: + new_body = body.replace(f"\\{orig_quote}", orig_quote).replace( + new_quote, f"\\{new_quote}" + ) if new_quote == '"""' and new_body[-1] == '"': # edge case: new_body = new_body[:-1] + '\\"' @@ -1932,7 +1942,6 @@ def normalize_string_quotes(leaf: Leaf) -> None: if new_escape_count == orig_escape_count and orig_quote == '"': return # Prefer double quotes - prefix = leaf.value[:first_quote_pos] leaf.value = f"{prefix}{new_quote}{new_body}{new_quote}" diff --git a/tests/string_quotes.py b/tests/string_quotes.py index 1080aaf..f2d720b 100644 --- a/tests/string_quotes.py +++ b/tests/string_quotes.py @@ -15,6 +15,9 @@ f'''This is a triple-quoted {f}-string''' f'MOAR {" ".join([])}' f"MOAR {' '.join([])}" r"raw string ftw" +r'Date d\'expiration:(.*)' +r'Tricky "quote' +r'Not-so-tricky \"quote' # output @@ -35,3 +38,6 @@ f"""This is a triple-quoted {f}-string""" f'MOAR {" ".join([])}' f"MOAR {' '.join([])}" r"raw string ftw" +r"Date d\'expiration:(.*)" +r'Tricky "quote' +r"Not-so-tricky \"quote"