Skip to content

Commit

Permalink
Fix parsing of nested f-string specifiers
Browse files Browse the repository at this point in the history
For an expression like `f"{one:{two:}{three}}"`, `three` is not in an f-string spec, and should be tokenized accordingly.

This PR fixes the `format_spec_count` bookkeeping in the tokenizer, so it properly decrements it when a closing `}` is encountered but only if the `}` closes a format_spec.

Reported in #930.
  • Loading branch information
zsol committed May 27, 2023
1 parent 110109a commit a5958d1
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 8 deletions.
4 changes: 0 additions & 4 deletions native/libcst/src/tokenizer/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,8 @@ pub enum TokType {
Dedent,
Async,
Await,
// TODO; add support for these
#[allow(dead_code)]
FStringStart,
#[allow(dead_code)]
FStringString,
#[allow(dead_code)]
FStringEnd,
EndMarker,
}
Expand Down
7 changes: 3 additions & 4 deletions native/libcst/src/tokenizer/core/string_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,10 @@ impl FStringNode {
}

pub fn close_parentheses(&mut self) {
self.parentheses_count -= 1;
if self.parentheses_count == 0 {
// No parentheses means that the format spec is also finished.
self.format_spec_count = 0;
if self.is_in_format_spec() {
self.format_spec_count -= 1;
}
self.parentheses_count -= 1;
}

pub fn allow_multiline(&self) -> bool {
Expand Down
26 changes: 26 additions & 0 deletions native/libcst/src/tokenizer/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,3 +814,29 @@ fn test_inconsistent_indentation_at_eof() {
])
)
}

#[test]
fn test_nested_f_string_specs() {
let config = TokConfig {
split_fstring: true,
..default_config()
};
assert_eq!(
tokenize_all("f'{_:{_:}{_}}'", &config),
Ok(vec![
(TokType::FStringStart, "f'"),
(TokType::Op, "{"),
(TokType::Name, "_"),
(TokType::Op, ":"),
(TokType::Op, "{"),
(TokType::Name, "_"),
(TokType::Op, ":"),
(TokType::Op, "}"),
(TokType::Op, "{"),
(TokType::Name, "_"),
(TokType::Op, "}"),
(TokType::Op, "}"),
(TokType::FStringEnd, "'")
])
)
}
2 changes: 2 additions & 0 deletions native/libcst/tests/fixtures/super_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@
f'\{{\}}'
f"regexp_like(path, '.*\{file_type}$')"
f"\lfoo"

f"{_:{_:}{a}}"

0 comments on commit a5958d1

Please sign in to comment.