[red-knot] Support calling a typing.Callable (#16888)
## Summary Part of #15382, this PR adds support for calling a variable that's annotated with `typing.Callable`. ## Test Plan Add test cases in a new `call/annotation.md` file.
This commit is contained in:
@@ -29,8 +29,6 @@ def i(callback: Callable[Concatenate[int, P], R_co], *args: P.args, **kwargs: P.
|
||||
# TODO: should understand the annotation
|
||||
reveal_type(kwargs) # revealed: dict
|
||||
|
||||
# TODO: not an error; remove once `call` is implemented for `Callable`
|
||||
# error: [call-non-callable]
|
||||
return callback(42, *args, **kwargs)
|
||||
|
||||
class Foo:
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# `typing.Callable`
|
||||
|
||||
```py
|
||||
from typing import Callable
|
||||
|
||||
def _(c: Callable[[], int]):
|
||||
reveal_type(c()) # revealed: int
|
||||
|
||||
def _(c: Callable[[int, str], int]):
|
||||
reveal_type(c(1, "a")) # revealed: int
|
||||
|
||||
# error: [invalid-argument-type] "Object of type `Literal["a"]` cannot be assigned to parameter 1; expected type `int`"
|
||||
# error: [invalid-argument-type] "Object of type `Literal[1]` cannot be assigned to parameter 2; expected type `str`"
|
||||
reveal_type(c("a", 1)) # revealed: int
|
||||
```
|
||||
|
||||
The `Callable` annotation can only be used to describe positional-only parameters.
|
||||
|
||||
```py
|
||||
def _(c: Callable[[int, str], None]):
|
||||
# error: [unknown-argument] "Argument `a` does not match any known parameter"
|
||||
# error: [unknown-argument] "Argument `b` does not match any known parameter"
|
||||
# error: [missing-argument] "No arguments provided for required parameters 1, 2"
|
||||
reveal_type(c(a=1, b="b")) # revealed: None
|
||||
```
|
||||
|
||||
If the annotation uses a gradual form (`...`) for the parameter list, then it can accept any kind of
|
||||
parameter with any type.
|
||||
|
||||
```py
|
||||
def _(c: Callable[..., int]):
|
||||
reveal_type(c()) # revealed: int
|
||||
reveal_type(c(1)) # revealed: int
|
||||
reveal_type(c(1, "str", False, a=[1, 2], b=(3, 4))) # revealed: int
|
||||
```
|
||||
|
||||
An invalid `Callable` form can accept any parameters and will return `Unknown`.
|
||||
|
||||
```py
|
||||
# error: [invalid-type-form]
|
||||
def _(c: Callable[42, str]):
|
||||
reveal_type(c()) # revealed: Unknown
|
||||
```
|
||||
Reference in New Issue
Block a user