@@ -123,35 +123,96 @@ set_ftstring_expr(struct tok_state* tok, struct token *token, char c) {
123123
124124// Check if there is a # character in the expression
125125int hash_detected = 0 ;
126+ int in_string = 0 ;
127+ char string_quote = 0 ;
126128for (Py_ssize_t i = 0 ;i < tok_mode -> last_expr_size - tok_mode -> last_expr_end ;i ++ ) {
127- if (tok_mode -> last_expr_buffer [i ]== '#' ) {
129+ char ch = tok_mode -> last_expr_buffer [i ];
130+ if (ch == '\\' && i + 1 < tok_mode -> last_expr_size - tok_mode -> last_expr_end ) {
131+ // Skip the next character if it's an escape sequence
132+ i ++ ;
133+ continue ;
134+ }
135+ if (ch == '"' || ch == '\'' ) {
136+ if (!in_string ) {
137+ in_string = 1 ;
138+ string_quote = ch ;
139+ }else if (ch == string_quote ) {
140+ // Check for triple quotes
141+ if (i > 0 && tok_mode -> last_expr_buffer [i - 1 ]== ch &&
142+ i > 1 && tok_mode -> last_expr_buffer [i - 2 ]== ch ) {
143+ // Skip the rest of the triple quote
144+ i += 2 ;
145+ }
146+ in_string = 0 ;
147+ }
148+ }else if (ch == '#' && !in_string ) {
128149hash_detected = 1 ;
129150break ;
130151 }
131152 }
132-
153+ // If we found a # character in the expression, we need to handle comments
133154if (hash_detected ) {
155+ // Calculate length of input we need to process
134156Py_ssize_t input_length = tok_mode -> last_expr_size - tok_mode -> last_expr_end ;
157+
158+ // Allocate buffer for processed result, with room for null terminator
135159char * result = (char * )PyMem_Malloc ((input_length + 1 )* sizeof (char ));
136160if (!result ) {
137161return -1 ;
138162 }
139163
140- Py_ssize_t i = 0 ;
141- Py_ssize_t j = 0 ;
164+ // Initialize counters and state
165+ Py_ssize_t i = 0 ;// Input position
166+ Py_ssize_t j = 0 ;// Output position
167+ in_string = 0 ;// Whether we're currently inside a string
168+ string_quote = 0 ;// The quote character for current string (' or ")
142169
170+ // Process each character of input
143171for (i = 0 ,j = 0 ;i < input_length ;i ++ ) {
144- if (tok_mode -> last_expr_buffer [i ]== '#' ) {
145- // Skip characters until newline or end of string
172+ char ch = tok_mode -> last_expr_buffer [i ];
173+
174+ // Handle escape sequences - copy both backslash and next char
175+ if (ch == '\\' && i + 1 < input_length ) {
176+ result [j ++ ]= ch ;// Copy backslash
177+ result [j ++ ]= tok_mode -> last_expr_buffer [++ i ];// Copy escaped char
178+ continue ;
179+ }
180+
181+ // Handle string quotes
182+ if (ch == '"' || ch == '\'' ) {
183+ if (!in_string ) {
184+ // Start of new string
185+ in_string = 1 ;
186+ string_quote = ch ;
187+ }else if (ch == string_quote ) {
188+ // Potential end of string - check for triple quotes
189+ if (i > 0 && tok_mode -> last_expr_buffer [i - 1 ]== ch &&
190+ i > 1 && tok_mode -> last_expr_buffer [i - 2 ]== ch ) {
191+ // Found triple quote - copy all three quotes
192+ result [j ++ ]= ch ;
193+ result [j ++ ]= ch ;
194+ result [j ++ ]= ch ;
195+ i += 2 ;// Skip the other two quotes
196+ continue ;
197+ }
198+ // End of regular string
199+ in_string = 0 ;
200+ }
201+ result [j ++ ]= ch ;// Copy the quote character
202+ }
203+ // Handle comments - skip everything until newline
204+ else if (ch == '#' && !in_string ) {
146205while (i < input_length && tok_mode -> last_expr_buffer [i ]!= '\0' ) {
147206if (tok_mode -> last_expr_buffer [i ]== '\n' ) {
148- result [j ++ ]= tok_mode -> last_expr_buffer [i ];
207+ result [j ++ ]= tok_mode -> last_expr_buffer [i ];// Keep newline
149208break ;
150209 }
151- i ++ ;
210+ i ++ ;// Skip comment character
152211 }
153- }else {
154- result [j ++ ]= tok_mode -> last_expr_buffer [i ];
212+ }
213+ // Copy any other character unchanged
214+ else {
215+ result [j ++ ]= ch ;
155216 }
156217 }
157218
@@ -164,11 +225,9 @@ set_ftstring_expr(struct tok_state* tok, struct token *token, char c) {
164225tok_mode -> last_expr_size - tok_mode -> last_expr_end ,
165226NULL
166227 );
167-
168228 }
169229
170-
171- if (!res ) {
230+ if (!res ) {
172231return -1 ;
173232 }
174233token -> metadata = res ;