diff --git a/crates/ruff_python_parser/src/lexer.rs b/crates/ruff_python_parser/src/lexer.rs index c2aa3772898fe9..3ba20e78e88e87 100644 --- a/crates/ruff_python_parser/src/lexer.rs +++ b/crates/ruff_python_parser/src/lexer.rs @@ -620,7 +620,7 @@ impl<'source> Lexer<'source> { } } '{' => { - if self.cursor.second() == '{' { + if self.cursor.second() == '{' && !fstring.is_in_format_spec(self.nesting) { self.cursor.bump(); normalized .push_str(&self.source[TextRange::new(last_offset, self.offset())]); @@ -2047,7 +2047,7 @@ def f(arg=%timeit a = b): #[test] fn test_fstring_with_format_spec() { - let source = r#"f"{foo:} {x=!s:.3f} {x:.{y}f} {'':*^{1:{1}}}""#; + let source = r#"f"{foo:} {x=!s:.3f} {x:.{y}f} {'':*^{1:{1}}} {x:{{1}.pop()}}""#; assert_debug_snapshot!(lex_source(source)); } diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap index c41165118ff93f..db324bdef0c2dd 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__fstring_with_format_spec.snap @@ -191,11 +191,76 @@ expression: lex_source(source) 43..44, ), ( - FStringEnd, + FStringMiddle { + value: " ", + is_raw: false, + }, 44..45, ), + ( + Lbrace, + 45..46, + ), + ( + Name { + name: "x", + }, + 46..47, + ), + ( + Colon, + 47..48, + ), + ( + Lbrace, + 48..49, + ), + ( + Lbrace, + 49..50, + ), + ( + Int { + value: 1, + }, + 50..51, + ), + ( + Rbrace, + 51..52, + ), + ( + Dot, + 52..53, + ), + ( + Name { + name: "pop", + }, + 53..56, + ), + ( + Lpar, + 56..57, + ), + ( + Rpar, + 57..58, + ), + ( + Rbrace, + 58..59, + ), + ( + Rbrace, + 59..60, + ), + ( + FStringEnd, + 60..61, + ), ( Newline, - 45..45, + 61..61, ), ]