From 47d80f29a7bb4f9fdf7153b112f4b5fde6b45a14 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Tue, 28 Nov 2023 14:38:25 -0600 Subject: [PATCH] Lexer start of line is false only for `Mode::Expression` (#8880) ## Summary This PR fixes the bug in the lexer where the `Mode::Ipython` wasn't being considered when initializing the soft keyword transformer which wraps the lexer. This means that if the source code starts with either `match` or `type` keyword, then the keywords were being considered as name tokens instead. For example, ```python match foo: case bar: pass ``` This would transform the `match` keyword into an identifier if the mode is `Ipython`. The fix is to reverse the condition in the soft keyword initializer so that any new modes are by default considered as the lexer being at start of line. ## Test Plan Add a new test case for `Mode::Ipython` and verify the snapshot. fixes: #8870 --- crates/ruff_python_parser/src/lexer.rs | 8 +++ ..._tests__match_softkeyword_in_notebook.snap | 66 +++++++++++++++++++ .../ruff_python_parser/src/soft_keywords.rs | 2 +- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__match_softkeyword_in_notebook.snap diff --git a/crates/ruff_python_parser/src/lexer.rs b/crates/ruff_python_parser/src/lexer.rs index 2ce3d17c8e..3831bc28d0 100644 --- a/crates/ruff_python_parser/src/lexer.rs +++ b/crates/ruff_python_parser/src/lexer.rs @@ -2160,6 +2160,14 @@ f"{(lambda x:{x})}" assert_debug_snapshot!(lex_source(source)); } + #[test] + fn test_match_softkeyword_in_notebook() { + let source = r"match foo: + case bar: + pass"; + assert_debug_snapshot!(lex_jupyter_source(source)); + } + fn lex_fstring_error(source: &str) -> FStringErrorType { match lex(source, Mode::Module).find_map(std::result::Result::err) { Some(err) => match err.error { diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__match_softkeyword_in_notebook.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__match_softkeyword_in_notebook.snap new file mode 100644 index 0000000000..0512714bd4 --- /dev/null +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__match_softkeyword_in_notebook.snap @@ -0,0 +1,66 @@ +--- +source: crates/ruff_python_parser/src/lexer.rs +expression: lex_jupyter_source(source) +--- +[ + ( + Match, + 0..5, + ), + ( + Name { + name: "foo", + }, + 6..9, + ), + ( + Colon, + 9..10, + ), + ( + Newline, + 10..11, + ), + ( + Indent, + 11..15, + ), + ( + Case, + 15..19, + ), + ( + Name { + name: "bar", + }, + 20..23, + ), + ( + Colon, + 23..24, + ), + ( + Newline, + 24..25, + ), + ( + Indent, + 25..33, + ), + ( + Pass, + 33..37, + ), + ( + Newline, + 37..37, + ), + ( + Dedent, + 37..37, + ), + ( + Dedent, + 37..37, + ), +] diff --git a/crates/ruff_python_parser/src/soft_keywords.rs b/crates/ruff_python_parser/src/soft_keywords.rs index f7aab9c113..6d14dc7f37 100644 --- a/crates/ruff_python_parser/src/soft_keywords.rs +++ b/crates/ruff_python_parser/src/soft_keywords.rs @@ -31,7 +31,7 @@ where pub fn new(lexer: I, mode: Mode) -> Self { Self { underlying: lexer.multipeek(), // spell-checker:ignore multipeek - start_of_line: matches!(mode, Mode::Module), + start_of_line: !matches!(mode, Mode::Expression), } } }