Use match_typing_call_path in more sites (#9336)

Preferable as it avoids multiple `resolve_call_path` calls internally.
This commit is contained in:
Charlie Marsh 2023-12-31 15:47:01 -04:00 committed by GitHub
parent 195f7c097a
commit 686abbc97a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 23 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -76,31 +76,31 @@ impl<'a> TypingTarget<'a> {
) -> Option<Self> {
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| {
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,
op: Operator::BitOr,