
we don't accidentally add backslashes to them when normalizing quotes because that's invalid syntax! The problem this commit fixes is that matches would eat too much blocking important matches to occur. For example, here's one f-string body: {a}{b}{c} I know there's no risk of introducing backslashes here, but the regex already goes sideways with this. Throwing this example at regex101 I get: {a}{b}{c} # The As and Bs are the two matches, and the upper ---- ---- # case letters are the groups with those matches. aAaa bbBb ... we've missed the middle expression (so if any backslashes in a more complex example were introduced there we wouldn't bail out even though we should -- hence the bug). As it stands the regex needs somesort of extra character (or the start/end of the body) around the expressions but that isn't always the case as shown above. The fix implemented here is to turn the "eat a surrounding non-curly bracket character" groups ie. `(?:[^{]|^)` and `(?:[^}]|$)` into negative lookaheads and lookbehinds. This still guarantees the already specified rules but without problematically eating extra characters ^^
113 lines
2.3 KiB
Python
113 lines
2.3 KiB
Python
''''''
|
|
'\''
|
|
'"'
|
|
"'"
|
|
"\""
|
|
"Hello"
|
|
"Don't do that"
|
|
'Here is a "'
|
|
'What\'s the deal here?'
|
|
"What's the deal \"here\"?"
|
|
"And \"here\"?"
|
|
"""Strings with "" in them"""
|
|
'''Strings with "" in them'''
|
|
'''Here's a "'''
|
|
'''Here's a " '''
|
|
'''Just a normal triple
|
|
quote'''
|
|
f"just a normal {f} string"
|
|
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'
|
|
rf'{yay}'
|
|
'\n\
|
|
The \"quick\"\n\
|
|
brown fox\n\
|
|
jumps over\n\
|
|
the \'lazy\' dog.\n\
|
|
'
|
|
re.compile(r'[\\"]')
|
|
"x = ''; y = \"\""
|
|
"x = '''; y = \"\""
|
|
"x = ''''; y = \"\""
|
|
"x = '' ''; y = \"\""
|
|
"x = ''; y = \"\"\""
|
|
"x = '''; y = \"\"\"\""
|
|
"x = ''''; y = \"\"\"\"\""
|
|
"x = '' ''; y = \"\"\"\"\""
|
|
'unnecessary \"\"escaping'
|
|
"unnecessary \'\'escaping"
|
|
'\\""'
|
|
"\\''"
|
|
'Lots of \\\\\\\\\'quotes\''
|
|
f'{y * " "} \'{z}\''
|
|
f'{{y * " "}} \'{z}\''
|
|
f'\'{z}\' {y * " "}'
|
|
f'{y * x} \'{z}\''
|
|
'\'{z}\' {y * " "}'
|
|
'{y * x} \'{z}\''
|
|
|
|
# We must bail out if changing the quotes would introduce backslashes in f-string
|
|
# expressions. xref: https://github.com/psf/black/issues/2348
|
|
f"\"{b}\"{' ' * (long-len(b)+1)}: \"{sts}\",\n"
|
|
f"\"{a}\"{'hello' * b}\"{c}\""
|
|
|
|
# output
|
|
|
|
""""""
|
|
"'"
|
|
'"'
|
|
"'"
|
|
'"'
|
|
"Hello"
|
|
"Don't do that"
|
|
'Here is a "'
|
|
"What's the deal here?"
|
|
'What\'s the deal "here"?'
|
|
'And "here"?'
|
|
"""Strings with "" in them"""
|
|
"""Strings with "" in them"""
|
|
'''Here's a "'''
|
|
"""Here's a " """
|
|
"""Just a normal triple
|
|
quote"""
|
|
f"just a normal {f} string"
|
|
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"
|
|
rf"{yay}"
|
|
"\nThe \"quick\"\nbrown fox\njumps over\nthe 'lazy' dog.\n"
|
|
re.compile(r'[\\"]')
|
|
"x = ''; y = \"\""
|
|
"x = '''; y = \"\""
|
|
"x = ''''; y = \"\""
|
|
"x = '' ''; y = \"\""
|
|
'x = \'\'; y = """'
|
|
'x = \'\'\'; y = """"'
|
|
'x = \'\'\'\'; y = """""'
|
|
'x = \'\' \'\'; y = """""'
|
|
'unnecessary ""escaping'
|
|
"unnecessary ''escaping"
|
|
'\\""'
|
|
"\\''"
|
|
"Lots of \\\\\\\\'quotes'"
|
|
f'{y * " "} \'{z}\''
|
|
f"{{y * \" \"}} '{z}'"
|
|
f'\'{z}\' {y * " "}'
|
|
f"{y * x} '{z}'"
|
|
"'{z}' {y * \" \"}"
|
|
"{y * x} '{z}'"
|
|
|
|
# We must bail out if changing the quotes would introduce backslashes in f-string
|
|
# expressions. xref: https://github.com/psf/black/issues/2348
|
|
f"\"{b}\"{' ' * (long-len(b)+1)}: \"{sts}\",\n"
|
|
f"\"{a}\"{'hello' * b}\"{c}\""
|