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
This commit is contained in:
parent
f8e9544c93
commit
51b3b2624d
11
black.py
11
black.py
@ -1917,7 +1917,17 @@ 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)]
|
||||
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}"
|
||||
)
|
||||
@ -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}"
|
||||
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
||||
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'MOAR {" ".join([])}'
|
||||
f"MOAR {' '.join([])}"
|
||||
r"raw string ftw"
|
||||
r"Date d\'expiration:(.*)"
|
||||
r'Tricky "quote'
|
||||
r"Not-so-tricky \"quote"
|
||||
|
Loading…
Reference in New Issue
Block a user