Skip to content

Commit 33a56f1

Browse files
authored
Don't skip visiting non-tuple slice in typing.Annotated subscripts (#17201)
Fixes: #17196 ## Summary Skipping these nodes for malformed type expressions would lead to incorrect semantic state, which can in turn mean we emit false positives for rules like `unused-variable`(`F841`) ## Test Plan `cargo nextest run`
1 parent 5cee346 commit 33a56f1

File tree

2 files changed

+27
-1
lines changed
  • crates/ruff_linter/src

2 files changed

+27
-1
lines changed

crates/ruff_linter/src/checkers/ast/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1669,7 +1669,15 @@ impl<'a> Visitor<'a> for Checker<'a> {
16691669
}
16701670
self.visit_expr_context(ctx);
16711671
} else {
1672-
debug!("Found non-Expr::Tuple argument to PEP 593 Annotation.");
1672+
if self.semantic.in_type_definition() {
1673+
// this should potentially trigger some kind of violation in the
1674+
// future, since it would indicate an invalid type expression
1675+
debug!("Found non-Expr::Tuple argument to PEP 593 Annotation.");
1676+
}
1677+
// even if the expression is invalid as a type expression, we should
1678+
// still visit it so we don't accidentally treat variables as unused
1679+
self.visit_expr(slice);
1680+
self.visit_expr_context(ctx);
16731681
}
16741682
}
16751683
Some(typing::SubscriptKind::TypedDict) => {

crates/ruff_linter/src/rules/pyflakes/mod.rs

+18
Original file line numberDiff line numberDiff line change
@@ -4263,4 +4263,22 @@ lambda: fu
42634263
&[],
42644264
);
42654265
}
4266+
4267+
#[test]
4268+
fn gh_issue_17196_regression_test() {
4269+
flakes(
4270+
r#"
4271+
from typing import Annotated
4272+
4273+
def type_annotations_from_tuple():
4274+
annos = (str, "foo", "bar")
4275+
return Annotated[annos]
4276+
4277+
def type_annotations_from_filtered_tuple():
4278+
annos = (str, None, "foo", None, "bar")
4279+
return Annotated[tuple([a for a in annos if a is not None])]
4280+
"#,
4281+
&[],
4282+
);
4283+
}
42664284
}

0 commit comments

Comments
 (0)