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

Commit05b3ce7

Browse files
authored
GH-103718: Correctly cache and restore f-string buffers when needed (GH-103719)
1 parent5041c2b commit05b3ce7

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-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: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -361,21 +361,35 @@ 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+
/* Traverse and restore all f-string buffers after reallocating tok->buf */
382+
staticvoid
383+
restore_fstring_buffers(structtok_state*tok)
384+
{
385+
intindex;
386+
tokenizer_mode*mode;
387+
388+
for (index=tok->tok_mode_stack_index;index >=0;--index) {
389+
mode=&(tok->tok_mode_stack[index]);
390+
if (mode->kind==TOK_FSTRING_MODE) {
391+
mode->f_string_start=tok->buf+mode->f_string_start_offset;
392+
mode->f_string_multi_line_start=tok->buf+mode->f_string_multi_line_start_offset;
379393
}
380394
}
381395
}
@@ -476,7 +490,7 @@ tok_reserve_buf(struct tok_state *tok, Py_ssize_t size)
476490
Py_ssize_tstart=tok->start==NULL ?-1 :tok->start-tok->buf;
477491
Py_ssize_tline_start=tok->start==NULL ?-1 :tok->line_start-tok->buf;
478492
Py_ssize_tmulti_line_start=tok->multi_line_start-tok->buf;
479-
update_fstring_buffers(tok,-*tok->buf,/*regular=*/1,/*multiline=*/1);
493+
remember_fstring_buffers(tok);
480494
newbuf= (char*)PyMem_Realloc(newbuf,newsize);
481495
if (newbuf==NULL) {
482496
tok->done=E_NOMEM;
@@ -489,7 +503,7 @@ tok_reserve_buf(struct tok_state *tok, Py_ssize_t size)
489503
tok->start=start<0 ?NULL :tok->buf+start;
490504
tok->line_start=line_start<0 ?NULL :tok->buf+line_start;
491505
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);
506+
restore_fstring_buffers(tok);
493507
}
494508
return1;
495509
}
@@ -1051,7 +1065,7 @@ tok_underflow_interactive(struct tok_state *tok) {
10511065
}
10521066
elseif (tok->start!=NULL) {
10531067
Py_ssize_tcur_multi_line_start=tok->multi_line_start-tok->buf;
1054-
update_fstring_buffers(tok,-*tok->buf,/*regular=*/0,/*multiline=*/1);
1068+
remember_fstring_buffers(tok);
10551069
size_tsize=strlen(newtok);
10561070
ADVANCE_LINENO();
10571071
if (!tok_reserve_buf(tok,size+1)) {
@@ -1064,7 +1078,7 @@ tok_underflow_interactive(struct tok_state *tok) {
10641078
PyMem_Free(newtok);
10651079
tok->inp+=size;
10661080
tok->multi_line_start=tok->buf+cur_multi_line_start;
1067-
update_fstring_buffers(tok,*tok->buf,/*regular=*/0,/*multiline=*/1);
1081+
restore_fstring_buffers(tok);
10681082
}
10691083
else {
10701084
ADVANCE_LINENO();
@@ -2207,6 +2221,8 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
22072221
the_current_tok->f_string_quote_size=quote_size;
22082222
the_current_tok->f_string_start=tok->start;
22092223
the_current_tok->f_string_multi_line_start=tok->line_start;
2224+
the_current_tok->f_string_start_offset=-1;
2225+
the_current_tok->f_string_multi_line_start_offset=-1;
22102226
the_current_tok->last_expr_buffer=NULL;
22112227
the_current_tok->last_expr_size=0;
22122228
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