@@ -2190,7 +2190,6 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
2190
2190
current_tok -> last_expr_buffer = NULL ;
2191
2191
current_tok -> last_expr_size = 0 ;
2192
2192
current_tok -> last_expr_end = -1 ;
2193
- current_tok -> format_spec = 0 ;
2194
2193
2195
2194
switch (* tok -> start ) {
2196
2195
case 'F' :
@@ -2326,7 +2325,6 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
2326
2325
2327
2326
if (c == ':' && cursor == mark ) {
2328
2327
current_tok -> kind = TOK_FSTRING_MODE ;
2329
- current_tok -> format_spec = 1 ;
2330
2328
p_start = tok -> start ;
2331
2329
p_end = tok -> cur ;
2332
2330
return MAKE_TOKEN (_PyToken_OneChar (c ));
@@ -2400,12 +2398,6 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
2400
2398
if (tok -> tok_mode_stack_index > 0 ) {
2401
2399
current_tok -> bracket_stack -- ;
2402
2400
if (c == '}' && current_tok -> bracket_stack == current_tok -> bracket_mark [current_tok -> bracket_mark_index ]) {
2403
- // When the expression is complete, we can exit the format
2404
- // spec mode (no matter if we were in it or not).
2405
- if (current_tok -> bracket_mark_index <= 0 ) {
2406
- current_tok -> format_spec = 0 ;
2407
- }
2408
-
2409
2401
current_tok -> bracket_mark_index -- ;
2410
2402
current_tok -> kind = TOK_FSTRING_MODE ;
2411
2403
}
@@ -2504,11 +2496,13 @@ tok_get_fstring_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct
2504
2496
return MAKE_TOKEN (FSTRING_MIDDLE );
2505
2497
}
2506
2498
char peek = tok_nextc (tok );
2507
- if (peek == '}' && current_tok -> bracket_mark_index <= 0
2508
- // We can not have }} inside the format spec, so we are going to assume
2509
- // this that the first closing brace belongs to the f-string expression
2510
- // and the second one needs to deal with later (e.g. f"{1:<3}}}").
2511
- && !current_tok -> format_spec ) {
2499
+
2500
+ // The tokenizer can only be in the format spec if we have already completed the expression
2501
+ // scanning (indicated by the end of the expression being set) and we are not at the top level
2502
+ // of the bracket stack (-1 is the top level). Since format specifiers can't legally use double
2503
+ // brackets, we can bypass it here.
2504
+ int in_format_spec = current_tok -> last_expr_end != -1 && current_tok -> bracket_mark_index >= 0 ;
2505
+ if (peek == '}' && !in_format_spec ) {
2512
2506
p_start = tok -> start ;
2513
2507
p_end = tok -> cur - 1 ;
2514
2508
} else {
0 commit comments