Skip to content

Commit d59feb5

Browse files
authored
gh-112243: Don't include comments in f-string debug expressions (#112284)
1 parent 3b3ec0d commit d59feb5

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

Lib/test/test_fstring.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,9 @@ def __repr__(self):
16271627
self.assertEqual(f'X{x = }Y', 'Xx = '+repr(x)+'Y')
16281628
self.assertEqual(f"sadsd {1 + 1 = :{1 + 1:1d}f}", "sadsd 1 + 1 = 2.000000")
16291629

1630+
self.assertEqual(f"{1+2 = # my comment
1631+
}", '1+2 = \n 3')
1632+
16301633
# These next lines contains tabs. Backslash escapes don't
16311634
# work in f-strings.
16321635
# patchcheck doesn't like these tabs. So the only way to test
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Don't include comments in f-string debug expressions. Patch by Pablo Galindo

Parser/lexer/lexer.c

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,56 @@ set_fstring_expr(struct tok_state* tok, struct token *token, char c) {
116116
if (!tok_mode->f_string_debug || token->metadata) {
117117
return 0;
118118
}
119+
PyObject *res = NULL;
119120

120-
PyObject *res = PyUnicode_DecodeUTF8(
121-
tok_mode->last_expr_buffer,
122-
tok_mode->last_expr_size - tok_mode->last_expr_end,
123-
NULL
124-
);
125-
if (!res) {
121+
// Check if there is a # character in the expression
122+
int hash_detected = 0;
123+
for (Py_ssize_t i = 0; i < tok_mode->last_expr_size - tok_mode->last_expr_end; i++) {
124+
if (tok_mode->last_expr_buffer[i] == '#') {
125+
hash_detected = 1;
126+
break;
127+
}
128+
}
129+
130+
if (hash_detected) {
131+
Py_ssize_t input_length = tok_mode->last_expr_size - tok_mode->last_expr_end;
132+
char *result = (char *)PyObject_Malloc((input_length + 1) * sizeof(char));
133+
if (!result) {
134+
return -1;
135+
}
136+
137+
Py_ssize_t i = 0;
138+
Py_ssize_t j = 0;
139+
140+
for (i = 0, j = 0; i < input_length; i++) {
141+
if (tok_mode->last_expr_buffer[i] == '#') {
142+
// Skip characters until newline or end of string
143+
while (tok_mode->last_expr_buffer[i] != '\0' && i < input_length) {
144+
if (tok_mode->last_expr_buffer[i] == '\n') {
145+
result[j++] = tok_mode->last_expr_buffer[i];
146+
break;
147+
}
148+
i++;
149+
}
150+
} else {
151+
result[j++] = tok_mode->last_expr_buffer[i];
152+
}
153+
}
154+
155+
result[j] = '\0'; // Null-terminate the result string
156+
res = PyUnicode_DecodeUTF8(result, j, NULL);
157+
PyObject_Free(result);
158+
} else {
159+
res = PyUnicode_DecodeUTF8(
160+
tok_mode->last_expr_buffer,
161+
tok_mode->last_expr_size - tok_mode->last_expr_end,
162+
NULL
163+
);
164+
165+
}
166+
167+
168+
if (!res) {
126169
return -1;
127170
}
128171
token->metadata = res;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy