Merge pull request #973 from pre-commit/string-fixer-3-12

don't rewrite string quotes inside f-strings
This commit is contained in:
Anthony Sottile 2023-10-07 13:53:40 -04:00 committed by GitHub
commit ae9b59f2d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 1 deletions

View File

@ -3,9 +3,16 @@ from __future__ import annotations
import argparse
import io
import re
import sys
import tokenize
from typing import Sequence
if sys.version_info >= (3, 12): # pragma: >=3.12 cover
FSTRING_START = tokenize.FSTRING_START
FSTRING_END = tokenize.FSTRING_END
else: # pragma: <3.12 cover
FSTRING_START = FSTRING_END = -1
START_QUOTE_RE = re.compile('^[a-zA-Z]*"')
@ -40,11 +47,17 @@ def fix_strings(filename: str) -> int:
# Basically a mutable string
splitcontents = list(contents)
fstring_depth = 0
# Iterate in reverse so the offsets are always correct
tokens_l = list(tokenize.generate_tokens(io.StringIO(contents).readline))
tokens = reversed(tokens_l)
for token_type, token_text, (srow, scol), (erow, ecol), _ in tokens:
if token_type == tokenize.STRING:
if token_type == FSTRING_START: # pragma: >=3.12 cover
fstring_depth += 1
elif token_type == FSTRING_END: # pragma: >=3.12 cover
fstring_depth -= 1
elif fstring_depth == 0 and token_type == tokenize.STRING:
new_text = handle_match(token_text)
splitcontents[
line_offsets[srow] + scol:

View File

@ -37,6 +37,12 @@ TESTS = (
1,
),
('"foo""bar"', "'foo''bar'", 1),
pytest.param(
"f'hello{\"world\"}'",
"f'hello{\"world\"}'",
0,
id='ignore nested fstrings',
),
)