Skip to content

Commit ae9b59f

Browse files
authored
Merge pull request #973 from pre-commit/string-fixer-3-12
don't rewrite string quotes inside f-strings
2 parents 6cad770 + f27ee31 commit ae9b59f

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

pre_commit_hooks/string_fixer.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@
33
import argparse
44
import io
55
import re
6+
import sys
67
import tokenize
78
from typing import Sequence
89

10+
if sys.version_info >= (3, 12): # pragma: >=3.12 cover
11+
FSTRING_START = tokenize.FSTRING_START
12+
FSTRING_END = tokenize.FSTRING_END
13+
else: # pragma: <3.12 cover
14+
FSTRING_START = FSTRING_END = -1
15+
916
START_QUOTE_RE = re.compile('^[a-zA-Z]*"')
1017

1118

@@ -40,11 +47,17 @@ def fix_strings(filename: str) -> int:
4047
# Basically a mutable string
4148
splitcontents = list(contents)
4249

50+
fstring_depth = 0
51+
4352
# Iterate in reverse so the offsets are always correct
4453
tokens_l = list(tokenize.generate_tokens(io.StringIO(contents).readline))
4554
tokens = reversed(tokens_l)
4655
for token_type, token_text, (srow, scol), (erow, ecol), _ in tokens:
47-
if token_type == tokenize.STRING:
56+
if token_type == FSTRING_START: # pragma: >=3.12 cover
57+
fstring_depth += 1
58+
elif token_type == FSTRING_END: # pragma: >=3.12 cover
59+
fstring_depth -= 1
60+
elif fstring_depth == 0 and token_type == tokenize.STRING:
4861
new_text = handle_match(token_text)
4962
splitcontents[
5063
line_offsets[srow] + scol:

tests/string_fixer_test.py

+6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
1,
3838
),
3939
('"foo""bar"', "'foo''bar'", 1),
40+
pytest.param(
41+
"f'hello{\"world\"}'",
42+
"f'hello{\"world\"}'",
43+
0,
44+
id='ignore nested fstrings',
45+
),
4046
)
4147

4248

0 commit comments

Comments
 (0)