From 686abbc97a5de35593dac9ffcaed35d45329d3b0 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 31 Dec 2023 15:47:01 -0400 Subject: [PATCH] Use `match_typing_call_path` in more sites (#9336) Preferable as it avoids multiple `resolve_call_path` calls internally. --- .../boolean_type_hint_positional_argument.rs | 11 +++++- .../flake8_pyi/rules/exit_annotations.rs | 12 +++++- crates/ruff_linter/src/rules/ruff/typing.rs | 38 +++++++++---------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs index 8cfefd02f8..1322deb207 100644 --- a/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs +++ b/crates/ruff_linter/src/rules/flake8_boolean_trap/rules/boolean_type_hint_positional_argument.rs @@ -191,7 +191,11 @@ fn match_annotation_to_complex_bool(annotation: &Expr, semantic: &SemanticModel) } // Ex) `typing.Union[bool, int]` Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => { - if semantic.match_typing_expr(value, "Union") { + let call_path = semantic.resolve_call_path(value); + if call_path + .as_ref() + .is_some_and(|call_path| semantic.match_typing_call_path(call_path, "Union")) + { if let Expr::Tuple(ast::ExprTuple { elts, .. }) = slice.as_ref() { elts.iter() .any(|elt| match_annotation_to_complex_bool(elt, semantic)) @@ -199,7 +203,10 @@ fn match_annotation_to_complex_bool(annotation: &Expr, semantic: &SemanticModel) // Union with a single type is an invalid type annotation false } - } else if semantic.match_typing_expr(value, "Optional") { + } else if call_path + .as_ref() + .is_some_and(|call_path| semantic.match_typing_call_path(call_path, "Optional")) + { match_annotation_to_complex_bool(slice, semantic) } else { false diff --git a/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs b/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs index 64c78394b8..b4081e3c6a 100644 --- a/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs +++ b/crates/ruff_linter/src/rules/flake8_pyi/rules/exit_annotations.rs @@ -244,7 +244,12 @@ fn non_none_annotation_element<'a>( ) -> Option<&'a Expr> { // E.g., `typing.Union` or `typing.Optional` if let Expr::Subscript(ExprSubscript { value, slice, .. }) = annotation { - if semantic.match_typing_expr(value, "Optional") { + let call_path = semantic.resolve_call_path(value); + + if call_path + .as_ref() + .is_some_and(|value| semantic.match_typing_call_path(value, "Optional")) + { return if slice.is_none_literal_expr() { None } else { @@ -252,7 +257,10 @@ fn non_none_annotation_element<'a>( }; } - if !semantic.match_typing_expr(value, "Union") { + if !call_path + .as_ref() + .is_some_and(|value| semantic.match_typing_call_path(value, "Union")) + { return None; } diff --git a/crates/ruff_linter/src/rules/ruff/typing.rs b/crates/ruff_linter/src/rules/ruff/typing.rs index f01e89c3fd..76f825da8f 100644 --- a/crates/ruff_linter/src/rules/ruff/typing.rs +++ b/crates/ruff_linter/src/rules/ruff/typing.rs @@ -76,30 +76,30 @@ impl<'a> TypingTarget<'a> { ) -> Option { match expr { Expr::Subscript(ast::ExprSubscript { value, slice, .. }) => { - if semantic.match_typing_expr(value, "Optional") { - Some(TypingTarget::Optional(slice.as_ref())) - } else if semantic.match_typing_expr(value, "Literal") { - Some(TypingTarget::Literal(slice)) - } else if semantic.match_typing_expr(value, "Union") { - Some(TypingTarget::Union(slice)) - } else if semantic.match_typing_expr(value, "Annotated") { - resolve_slice_value(slice.as_ref()) - .next() - .map(TypingTarget::Annotated) - } else { - semantic.resolve_call_path(value).map_or( - // If we can't resolve the call path, it must be defined - // in the same file and could be a type alias. - Some(TypingTarget::Unknown), - |call_path| { + semantic.resolve_call_path(value).map_or( + // If we can't resolve the call path, it must be defined + // in the same file and could be a type alias. + Some(TypingTarget::Unknown), + |call_path| { + if semantic.match_typing_call_path(&call_path, "Optional") { + Some(TypingTarget::Optional(slice.as_ref())) + } else if semantic.match_typing_call_path(&call_path, "Literal") { + Some(TypingTarget::Literal(slice.as_ref())) + } else if semantic.match_typing_call_path(&call_path, "Union") { + Some(TypingTarget::Union(slice.as_ref())) + } else if semantic.match_typing_call_path(&call_path, "Annotated") { + resolve_slice_value(slice.as_ref()) + .next() + .map(TypingTarget::Annotated) + } else { if is_known_type(&call_path, minor_version) { Some(TypingTarget::Known) } else { Some(TypingTarget::Unknown) } - }, - ) - } + } + }, + ) } Expr::BinOp(ast::ExprBinOp { left,