mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-03 15:15:33 +00:00
[ty] Fix panic when trying to pull types for subscript expressions inside Callable
type expressions (#18534)
This commit is contained in:
parent
475a02b725
commit
aa3c312f5f
4 changed files with 61 additions and 17 deletions
|
@ -252,6 +252,31 @@ def _(c: Callable[[Concatenate[int, str, ...], int], int]):
|
|||
reveal_type(c) # revealed: (...) -> int
|
||||
```
|
||||
|
||||
Other type expressions can be nested inside `Concatenate`:
|
||||
|
||||
```py
|
||||
def _(c: Callable[[Concatenate[int | str, type[str], ...], int], int]):
|
||||
# TODO: Should reveal the correct signature
|
||||
reveal_type(c) # revealed: (...) -> int
|
||||
```
|
||||
|
||||
But providing fewer than 2 arguments to `Concatenate` is an error:
|
||||
|
||||
```py
|
||||
# fmt: off
|
||||
|
||||
def _(
|
||||
c: Callable[Concatenate[int], int], # error: [invalid-type-form] "Special form `typing.Concatenate` expected at least 2 parameters but got 1"
|
||||
d: Callable[Concatenate[(int,)], int], # error: [invalid-type-form] "Special form `typing.Concatenate` expected at least 2 parameters but got 1"
|
||||
e: Callable[Concatenate[()], int] # error: [invalid-type-form] "Special form `typing.Concatenate` expected at least 2 parameters but got 0"
|
||||
):
|
||||
reveal_type(c) # revealed: (...) -> int
|
||||
reveal_type(d) # revealed: (...) -> int
|
||||
reveal_type(e) # revealed: (...) -> int
|
||||
|
||||
# fmt: on
|
||||
```
|
||||
|
||||
## Using `typing.ParamSpec`
|
||||
|
||||
```toml
|
||||
|
|
|
@ -9441,8 +9441,29 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
|||
todo_type!("`TypeGuard[]` special form")
|
||||
}
|
||||
SpecialFormType::Concatenate => {
|
||||
self.infer_type_expression(arguments_slice);
|
||||
todo_type!("`Concatenate[]` special form")
|
||||
let arguments = if let ast::Expr::Tuple(tuple) = arguments_slice {
|
||||
&*tuple.elts
|
||||
} else {
|
||||
std::slice::from_ref(arguments_slice)
|
||||
};
|
||||
for argument in arguments {
|
||||
self.infer_type_expression(argument);
|
||||
}
|
||||
let num_arguments = arguments.len();
|
||||
let inferred_type = if num_arguments < 2 {
|
||||
if let Some(builder) = self.context.report_lint(&INVALID_TYPE_FORM, subscript) {
|
||||
builder.into_diagnostic(format_args!(
|
||||
"Special form `{special_form}` expected at least 2 parameters but got {num_arguments}",
|
||||
));
|
||||
}
|
||||
Type::unknown()
|
||||
} else {
|
||||
todo_type!("`Concatenate[]` special form")
|
||||
};
|
||||
if arguments_slice.is_tuple_expr() {
|
||||
self.store_expression_type(arguments_slice, inferred_type);
|
||||
}
|
||||
inferred_type
|
||||
}
|
||||
SpecialFormType::Unpack => {
|
||||
self.infer_type_expression(arguments_slice);
|
||||
|
@ -9622,7 +9643,9 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
|||
}))
|
||||
});
|
||||
}
|
||||
ast::Expr::Subscript(_) => {
|
||||
ast::Expr::Subscript(subscript) => {
|
||||
let value_ty = self.infer_expression(&subscript.value);
|
||||
self.infer_subscript_type_expression(subscript, value_ty);
|
||||
// TODO: Support `Concatenate[...]`
|
||||
return Some(Parameters::todo());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue