MCPcopy Index your code
hub / github.com/RustPython/RustPython / parse_fstring_middle

Method parse_fstring_middle

crates/codegen/src/string_parser.rs:156–228  ·  view source on GitHub ↗
(mut self)

Source from the content-addressed store, hash-verified

154 }
155
156 fn parse_fstring_middle(mut self) -> Result<Box<Wtf8>, LexicalError> {
157 // Fast-path: if the f-string doesn't contain any escape sequences, return the literal.
158 let Some(mut index) = memchr::memchr3(b'{', b'}', b'\\', self.source.as_bytes()) else {
159 return Ok(self.source.into());
160 };
161
162 let mut value = Wtf8Buf::with_capacity(self.source.len());
163 loop {
164 // Add the characters before the escape sequence (or curly brace) to the string.
165 let before_with_slash_or_brace = self.skip_bytes(index + 1);
166 let before = &before_with_slash_or_brace[..before_with_slash_or_brace.len() - 1];
167 value.push_str(before);
168
169 // Add the escaped character to the string.
170 match &self.source.as_bytes()[self.cursor - 1] {
171 // If there are any curly braces inside a `FStringMiddle` token,
172 // then they were escaped (i.e. `{{` or `}}`). This means that
173 // we need increase the location by 2 instead of 1.
174 b'{' => value.push_char('{'),
175 b'}' => value.push_char('}'),
176 // We can encounter a `\` as the last character in a `FStringMiddle`
177 // token which is valid in this context. For example,
178 //
179 // ```python
180 // f"\{foo} \{bar:\}"
181 // # ^ ^^ ^
182 // ```
183 //
184 // Here, the `FStringMiddle` token content will be "\" and " \"
185 // which is invalid if we look at the content in isolation:
186 //
187 // ```python
188 // "\"
189 // ```
190 //
191 // However, the content is syntactically valid in the context of
192 // the f-string because it's a substring of the entire f-string.
193 // This is still an invalid escape sequence, but we don't want to
194 // raise a syntax error as is done by the CPython parser. It might
195 // be supported in the future, refer to point 3: https://peps.python.org/pep-0701/#rejected-ideas
196 b'\\' => {
197 if !self.flags.is_raw_string() && self.peek_byte().is_some() {
198 match self.parse_escaped_char()? {
199 None => {}
200 Some(EscapedChar::Literal(c)) => value.push(c),
201 Some(EscapedChar::Escape(c)) => {
202 value.push_char('\\');
203 value.push_char(c);
204 }
205 }
206 } else {
207 value.push_char('\\');
208 }
209 }
210 ch => {
211 unreachable!("Expected '{{', '}}', or '\\' but got {:?}", ch);
212 }
213 }

Callers 1

Calls 8

skip_bytesMethod · 0.80
parse_escaped_charMethod · 0.80
as_bytesMethod · 0.45
lenMethod · 0.45
push_strMethod · 0.45
push_charMethod · 0.45
peek_byteMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected