Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita73c5c6

Browse files
committed
GH-103718: Correctly cache and restore f-string buffers when needed
1 parent0056701 commita73c5c6

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

‎Lib/test/test_fstring.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,5 +1532,10 @@ def test_syntax_error_for_starred_expressions(self):
15321532
"f-string: expecting a valid expression after '{'"):
15331533
compile("f'{**a}'","?","exec")
15341534

1535+
deftest_not_closing_quotes(self):
1536+
self.assertAllRaise(SyntaxError,"unterminated f-string literal", ['f"',"f'"])
1537+
self.assertAllRaise(SyntaxError,"unterminated triple-quoted f-string literal",
1538+
['f"""',"f'''"])
1539+
15351540
if__name__=='__main__':
15361541
unittest.main()

‎Parser/tokenizer.c‎

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -361,21 +361,36 @@ tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) {
361361
return0;
362362
}
363363

364-
365-
/* Traverse and update all f-string buffers with the value */
364+
/* Traverse and remember all f-string buffers, in order to be able to restore
365+
them after reallocating tok->buf */
366366
staticvoid
367-
update_fstring_buffers(structtok_state*tok,charvalue,intregular,intmultiline)
367+
remember_fstring_buffers(structtok_state*tok)
368368
{
369369
intindex;
370370
tokenizer_mode*mode;
371371

372372
for (index=tok->tok_mode_stack_index;index >=0;--index) {
373373
mode=&(tok->tok_mode_stack[index]);
374-
if (regular&&mode->f_string_start!=NULL) {
375-
mode->f_string_start+=value;
374+
if (mode->kind==TOK_FSTRING_MODE) {
375+
mode->f_string_start_offset=mode->f_string_start-tok->buf;
376+
mode->f_string_multi_line_start_offset=mode->f_string_multi_line_start-tok->buf;
376377
}
377-
if (multiline&&mode->f_string_multi_line_start!=NULL) {
378-
mode->f_string_multi_line_start+=value;
378+
}
379+
}
380+
381+
382+
/* Traverse and restore all f-string buffers after reallocating tok->buf */
383+
staticvoid
384+
restore_fstring_buffers(structtok_state*tok)
385+
{
386+
intindex;
387+
tokenizer_mode*mode;
388+
389+
for (index=tok->tok_mode_stack_index;index >=0;--index) {
390+
mode=&(tok->tok_mode_stack[index]);
391+
if (mode->kind==TOK_FSTRING_MODE) {
392+
mode->f_string_start=tok->buf+mode->f_string_start_offset;
393+
mode->f_string_multi_line_start=tok->buf+mode->f_string_multi_line_start_offset;
379394
}
380395
}
381396
}
@@ -476,7 +491,7 @@ tok_reserve_buf(struct tok_state *tok, Py_ssize_t size)
476491
Py_ssize_tstart=tok->start==NULL ?-1 :tok->start-tok->buf;
477492
Py_ssize_tline_start=tok->start==NULL ?-1 :tok->line_start-tok->buf;
478493
Py_ssize_tmulti_line_start=tok->multi_line_start-tok->buf;
479-
update_fstring_buffers(tok,-*tok->buf,/*regular=*/1,/*multiline=*/1);
494+
remember_fstring_buffers(tok);
480495
newbuf= (char*)PyMem_Realloc(newbuf,newsize);
481496
if (newbuf==NULL) {
482497
tok->done=E_NOMEM;
@@ -489,7 +504,7 @@ tok_reserve_buf(struct tok_state *tok, Py_ssize_t size)
489504
tok->start=start<0 ?NULL :tok->buf+start;
490505
tok->line_start=line_start<0 ?NULL :tok->buf+line_start;
491506
tok->multi_line_start=multi_line_start<0 ?NULL :tok->buf+multi_line_start;
492-
update_fstring_buffers(tok,*tok->buf,/*regular=*/1,/*multiline=*/1);
507+
restore_fstring_buffers(tok);
493508
}
494509
return1;
495510
}
@@ -1051,7 +1066,7 @@ tok_underflow_interactive(struct tok_state *tok) {
10511066
}
10521067
elseif (tok->start!=NULL) {
10531068
Py_ssize_tcur_multi_line_start=tok->multi_line_start-tok->buf;
1054-
update_fstring_buffers(tok,-*tok->buf,/*regular=*/0,/*multiline=*/1);
1069+
remember_fstring_buffers(tok);
10551070
size_tsize=strlen(newtok);
10561071
ADVANCE_LINENO();
10571072
if (!tok_reserve_buf(tok,size+1)) {
@@ -1064,7 +1079,7 @@ tok_underflow_interactive(struct tok_state *tok) {
10641079
PyMem_Free(newtok);
10651080
tok->inp+=size;
10661081
tok->multi_line_start=tok->buf+cur_multi_line_start;
1067-
update_fstring_buffers(tok,*tok->buf,/*regular=*/0,/*multiline=*/1);
1082+
restore_fstring_buffers(tok);
10681083
}
10691084
else {
10701085
ADVANCE_LINENO();
@@ -2207,6 +2222,8 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
22072222
the_current_tok->f_string_quote_size=quote_size;
22082223
the_current_tok->f_string_start=tok->start;
22092224
the_current_tok->f_string_multi_line_start=tok->line_start;
2225+
the_current_tok->f_string_start_offset=-1;
2226+
the_current_tok->f_string_multi_line_start_offset=-1;
22102227
the_current_tok->last_expr_buffer=NULL;
22112228
the_current_tok->last_expr_size=0;
22122229
the_current_tok->last_expr_end=-1;

‎Parser/tokenizer.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ typedef struct _tokenizer_mode {
5252
constchar*f_string_start;
5353
constchar*f_string_multi_line_start;
5454

55+
Py_ssize_tf_string_start_offset;
56+
Py_ssize_tf_string_multi_line_start_offset;
57+
5558
Py_ssize_tlast_expr_size;
5659
Py_ssize_tlast_expr_end;
5760
char*last_expr_buffer;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp