Skip to content

Commit e71d87b

Browse files
committed
Add more tests
1 parent 52388f1 commit e71d87b

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

crates/red_knot_python_semantic/resources/mdtest/annotations/callable.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,35 @@ def _(c: Callable):
9191
reveal_type(c) # revealed: (*args: Any, **kwargs: Any) -> Any
9292
```
9393

94+
## Simple
95+
96+
A simple `Callable` with multiple parameters and a return type:
97+
98+
```py
99+
from typing import Callable
100+
101+
def _(c: Callable[[int, str], int]):
102+
reveal_type(c) # revealed: (int, str, /) -> int
103+
```
104+
105+
## Nested
106+
107+
A nested `Callable` as one of the parameter types:
108+
109+
```py
110+
from typing import Callable
111+
112+
def _(c: Callable[[Callable[[int], str]], int]):
113+
reveal_type(c) # revealed: ((int, /) -> str, /) -> int
114+
```
115+
116+
And, as the return type:
117+
118+
```py
119+
def _(c: Callable[[int, str], Callable[[int], int]]):
120+
reveal_type(c) # revealed: (int, str, /) -> (int, /) -> int
121+
```
122+
94123
## Gradual form
95124

96125
The `Callable` special form supports the use of `...` in place of the list of parameter types. This is a
@@ -109,4 +138,52 @@ gradual_form(lambda x: "hello")
109138
gradual_form(lambda x, y: "hello")
110139
```
111140

141+
## Using `typing.Concatenate`
142+
143+
```toml
144+
[environment]
145+
python-version = "3.10"
146+
```
147+
148+
Using `Concatenate` as the first argument to `Callable`:
149+
150+
```py
151+
from typing import Callable, Concatenate
152+
153+
def _(c: Callable[Concatenate[int, str, ...], int]):
154+
reveal_type(c) # revealed: (*args: @Todo(todo signature *args), **kwargs: @Todo(todo signature **kwargs)) -> int
155+
```
156+
157+
And, as one of the parameter types:
158+
159+
```py
160+
def _(c: Callable[[Concatenate[int, str, ...], int], int]):
161+
reveal_type(c) # revealed: (*args: @Todo(todo signature *args), **kwargs: @Todo(todo signature **kwargs)) -> int
162+
```
163+
164+
## Using `typing.ParamSpec`
165+
166+
```toml
167+
[environment]
168+
python-version = "3.10"
169+
```
170+
171+
Defining `ParamSpec` explicitly:
172+
173+
```py
174+
from typing import Callable, ParamSpec
175+
176+
P1 = ParamSpec("P1")
177+
178+
def _(c: Callable[P1, int]):
179+
reveal_type(c) # revealed: (*args: @Todo(todo signature *args), **kwargs: @Todo(todo signature **kwargs)) -> int
180+
```
181+
182+
And, defining it using generics:
183+
184+
```py
185+
def _[**P2](c: Callable[P2, int]):
186+
reveal_type(c) # revealed: (*args: @Todo(todo signature *args), **kwargs: @Todo(todo signature **kwargs)) -> int
187+
```
188+
112189
[gradual form]: https://typing.readthedocs.io/en/latest/spec/glossary.html#term-gradual-form

crates/red_knot_python_semantic/src/types/infer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6370,11 +6370,11 @@ impl<'db> TypeInferenceBuilder<'db> {
63706370
}
63716371
}
63726372
ast::Expr::Subscript(_) => {
6373-
// TODO: Support `Concatenate[...]` and `Unpack[...]`
6373+
// TODO: Support `Concatenate[...]`
63746374
Parameters::todo()
63756375
}
63766376
ast::Expr::Name(name) => {
6377-
// This is mainly to handle an edge case `Callable[]`
6377+
// This is mainly to handle an error case: `Callable[]`
63786378
if !name.is_valid() {
63796379
return Err(());
63806380
}

0 commit comments

Comments
 (0)