File tree Expand file tree Collapse file tree 2 files changed +42
-1
lines changed Expand file tree Collapse file tree 2 files changed +42
-1
lines changed Original file line number Diff line number Diff line change @@ -203,7 +203,13 @@ def build_logical_line_tokens(self) -> _Logical: # noqa: C901
203203 if token_type == tokenize .STRING :
204204 text = mutate_string (text )
205205 elif token_type == FSTRING_MIDDLE : # pragma: >=3.12 cover
206- text = "x" * len (text )
206+ # A curly brace in an FSTRING_MIDDLE token must be an escaped
207+ # curly brace. Both 'text' and 'end' will account for the
208+ # escaped version of the token (i.e. a single brace) rather
209+ # than the raw double brace version, so we must counteract this
210+ brace_offset = text .count ("{" ) + text .count ("}" )
211+ text = "x" * (len (text ) + brace_offset )
212+ end = (end [0 ], end [1 ] + brace_offset )
207213 if previous_row :
208214 (start_row , start_column ) = start
209215 if previous_row != start_row :
Original file line number Diff line number Diff line change 11"""Integration tests for plugin loading."""
22from __future__ import annotations
33
4+ import sys
5+
46import pytest
57
68from flake8 .main .cli import main
@@ -261,3 +263,36 @@ def test_logical_line_plugin(tmpdir, capsys):
261263"""
262264 out , err = capsys .readouterr ()
263265 assert out == expected
266+
267+
268+ def test_escaping_of_fstrings_in_string_redacter (tmpdir , capsys ):
269+ cfg_s = f"""\
270+ [flake8]
271+ extend-ignore = F
272+ [flake8:local-plugins]
273+ extension =
274+ T = { yields_logical_line .__module__ } :{ yields_logical_line .__name__ }
275+ """
276+
277+ cfg = tmpdir .join ("tox.ini" )
278+ cfg .write (cfg_s )
279+
280+ src = """\
281+ f'{{"{hello}": "{world}"}}'
282+ """
283+ t_py = tmpdir .join ("t.py" )
284+ t_py .write_binary (src .encode ())
285+
286+ with tmpdir .as_cwd ():
287+ assert main (("t.py" , "--config" , str (cfg ))) == 1
288+
289+ if sys .version_info >= (3 , 12 ): # pragma: >=3.12 cover
290+ expected = """\
291+ t.py:1:1: T001 "f'xxx{hello}xxxx{world}xxx'"
292+ """
293+ else : # pragma: <3.12 cover
294+ expected = """\
295+ t.py:1:1: T001 "f'xxxxxxxxxxxxxxxxxxxxxxxx'"
296+ """
297+ out , err = capsys .readouterr ()
298+ assert out == expected
You can’t perform that action at this time.
0 commit comments