MCPcopy Create free account
hub / github.com/astral-sh/ruff / parse_interpolated_string_middle

Method parse_interpolated_string_middle

crates/ruff_python_parser/src/string.rs:280–374  ·  view source on GitHub ↗
(
        mut self,
    )

Source from the content-addressed store, hash-verified

278 }
279
280 fn parse_interpolated_string_middle(
281 mut self,
282 ) -> Result<ast::InterpolatedStringLiteralElement, LexicalError> {
283 // Fast-path: if the f-string or t-string doesn't contain any escape sequences, return the literal.
284 let Some(mut index) = memchr::memchr3(b'{', b'}', b'\\', self.source.as_bytes()) else {
285 return Ok(ast::InterpolatedStringLiteralElement {
286 value: self.source.into(),
287 range: self.range,
288 node_index: AtomicNodeIndex::NONE,
289 });
290 };
291
292 let mut value = String::with_capacity(self.source.len());
293 loop {
294 // Add the characters before the escape sequence (or curly brace) to the string.
295 let before_with_slash_or_brace = self.skip_bytes(index + 1);
296 let before = &before_with_slash_or_brace[..before_with_slash_or_brace.len() - 1];
297 value.push_str(before);
298
299 // Add the escaped character to the string.
300 match self.source.as_bytes()[self.cursor - 1] {
301 // If there are any curly braces inside a `F/TStringMiddle` token,
302 // then they were escaped (i.e. `{{` or `}}`). This means that
303 // the raw source contains a doubled brace, but the literal value only
304 // contains one brace.
305 brace @ (b'{' | b'}') => {
306 if self.peek_byte() == Some(brace) {
307 self.next_byte();
308 }
309 value.push(char::from(brace));
310 }
311 // We can encounter a `\` as the last character in a `F/TStringMiddle`
312 // token which is valid in this context. For example,
313 //
314 // ```python
315 // f"\{foo} \{bar:\}"
316 // # ^ ^^ ^
317 // ```
318 //
319 // Here, the `F/TStringMiddle` token content will be "\" and " \"
320 // which is invalid if we look at the content in isolation:
321 //
322 // ```python
323 // "\"
324 // ```
325 //
326 // However, the content is syntactically valid in the context of
327 // the f/t-string because it's a substring of the entire f/t-string.
328 // This is still an invalid escape sequence, but we don't want to
329 // raise a syntax error as is done by the CPython parser. It might
330 // be supported in the future, refer to point 3: https://peps.python.org/pep-0701/#rejected-ideas
331 b'\\' => {
332 if !self.flags.is_raw_string() && self.peek_byte().is_some() {
333 if let Some(brace @ (b'{' | b'}')) = self.peek_byte()
334 && self.source.as_bytes().get(self.cursor + 1).copied() == Some(brace)
335 {
336 // Leave the doubled brace for the next iteration to collapse.
337 value.push('\\');

Calls 11

OkClass · 0.85
peek_byteMethod · 0.80
next_byteMethod · 0.80
parse_escaped_charMethod · 0.80
as_bytesMethod · 0.45
lenMethod · 0.45
skip_bytesMethod · 0.45
push_strMethod · 0.45
pushMethod · 0.45
is_raw_stringMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected