diff --git a/crates/ruff/resources/test/fixtures/pyflakes/F632.py b/crates/ruff/resources/test/fixtures/pyflakes/F632.py index 2e02341a7c..1940233218 100644 --- a/crates/ruff/resources/test/fixtures/pyflakes/F632.py +++ b/crates/ruff/resources/test/fixtures/pyflakes/F632.py @@ -19,3 +19,6 @@ if ("123" != x) is 3: if "123" != (x is 3): pass + +{2 is +not ''} diff --git a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F632_F632.py.snap b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F632_F632.py.snap index 7b1af9143a..8fa94a9b8d 100644 --- a/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F632_F632.py.snap +++ b/crates/ruff/src/rules/pyflakes/snapshots/ruff__rules__pyflakes__tests__F632_F632.py.snap @@ -136,5 +136,26 @@ F632.py:20:14: F632 [*] Use `==` to compare constant literals 20 |-if "123" != (x is 3): 20 |+if "123" != (x == 3): 21 21 | pass +22 22 | +23 23 | {2 is + +F632.py:23:2: F632 [*] Use `!=` to compare constant literals + | +23 | pass +24 | +25 | {2 is + | __^ +26 | | not ''} + | |______^ F632 + | + = help: Replace `is not` with `!=` + +ℹ Suggested fix +20 20 | if "123" != (x is 3): +21 21 | pass +22 22 | +23 |-{2 is +24 |-not ''} + 23 |+{2 != ''} diff --git a/crates/ruff_python_ast/src/helpers.rs b/crates/ruff_python_ast/src/helpers.rs index 9789e1abcb..dc620ceded 100644 --- a/crates/ruff_python_ast/src/helpers.rs +++ b/crates/ruff_python_ast/src/helpers.rs @@ -1440,14 +1440,21 @@ impl LocatedCmpop { } } -/// Extract all [`Cmpop`] operators from a source code snippet, with appropriate +/// Extract all [`Cmpop`] operators from an expression snippet, with appropriate /// ranges. /// /// `RustPython` doesn't include line and column information on [`Cmpop`] nodes. /// `CPython` doesn't either. This method iterates over the token stream and /// re-identifies [`Cmpop`] nodes, annotating them with valid ranges. pub fn locate_cmpops(contents: &str) -> Vec { - let mut tok_iter = lexer::lex(contents, Mode::Module).flatten().peekable(); + let mut tok_iter = lexer::lex(contents, Mode::Expression) + .flatten() + .filter(|(tok, _)| + // Skip whitespace, including Tok::Newline. It should be sufficient to skip + // Tok::NonLogicalNewline, but the lexer doesn't know that we're within an + // expression, and so it may confusion logical and non-logical newlines. + !matches!(tok, Tok::Newline | Tok::NonLogicalNewline | Tok::Comment(_))) + .peekable(); let mut ops: Vec = vec![]; let mut count = 0u32; loop {