From 2643f74a5db2c0a0c998327c5cefd8039e880234 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 17 Dec 2023 23:51:23 -0500 Subject: [PATCH] Iterate over lambdas in deferred type annotations (#9175) Closes https://github.com/astral-sh/ruff/issues/9159. --- .../resources/test/fixtures/pyflakes/F401_20.py | 4 ++++ crates/ruff_linter/src/checkers/ast/mod.rs | 8 +++++--- crates/ruff_linter/src/rules/pyflakes/mod.rs | 1 + ...f_linter__rules__pyflakes__tests__F401_F401_20.py.snap | 4 ++++ 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 crates/ruff_linter/resources/test/fixtures/pyflakes/F401_20.py create mode 100644 crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_20.py.snap diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F401_20.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F401_20.py new file mode 100644 index 0000000000000..3ab759cb61ca5 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F401_20.py @@ -0,0 +1,4 @@ +import re +from typing import Annotated + +type X = Annotated[int, lambda: re.compile("x")] diff --git a/crates/ruff_linter/src/checkers/ast/mod.rs b/crates/ruff_linter/src/checkers/ast/mod.rs index 1c510f1cbb8d9..2cc13787d731b 100644 --- a/crates/ruff_linter/src/checkers/ast/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/mod.rs @@ -2013,13 +2013,15 @@ pub(crate) fn check_ast( // Iterate over the AST. checker.visit_body(python_ast); - // Visit any deferred syntax nodes. + // Visit any deferred syntax nodes. Take care to visit in order, such that we avoid adding + // new deferred nodes after visiting nodes of that kind. For example, visiting a deferred + // function can add a deferred lambda, but the opposite is not true. checker.visit_deferred_functions(); - checker.visit_deferred_lambdas(); - checker.visit_deferred_future_type_definitions(); checker.visit_deferred_type_param_definitions(); + checker.visit_deferred_future_type_definitions(); let allocator = typed_arena::Arena::new(); checker.visit_deferred_string_type_definitions(&allocator); + checker.visit_deferred_lambdas(); checker.visit_exports(); // Check docstrings, bindings, and unresolved references. diff --git a/crates/ruff_linter/src/rules/pyflakes/mod.rs b/crates/ruff_linter/src/rules/pyflakes/mod.rs index 435755ce9fe42..814dcb3d743ec 100644 --- a/crates/ruff_linter/src/rules/pyflakes/mod.rs +++ b/crates/ruff_linter/src/rules/pyflakes/mod.rs @@ -52,6 +52,7 @@ mod tests { #[test_case(Rule::UnusedImport, Path::new("F401_17.py"))] #[test_case(Rule::UnusedImport, Path::new("F401_18.py"))] #[test_case(Rule::UnusedImport, Path::new("F401_19.py"))] + #[test_case(Rule::UnusedImport, Path::new("F401_20.py"))] #[test_case(Rule::ImportShadowedByLoopVar, Path::new("F402.py"))] #[test_case(Rule::UndefinedLocalWithImportStar, Path::new("F403.py"))] #[test_case(Rule::LateFutureImport, Path::new("F404.py"))] diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_20.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_20.py.snap new file mode 100644 index 0000000000000..d0b409f39ee0b --- /dev/null +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F401_F401_20.py.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/pyflakes/mod.rs +--- +