mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +00:00
[red-knot] Infer lambda
return type as Unknown
(#16695)
## Summary Part of #15382 This PR infers the return type `lambda` expression as `Unknown`. In the future, it would be more useful to infer the expression type considering the surrounding context (#16696). ## Test Plan Update existing test cases from `@todo` to the (verified) return type.
This commit is contained in:
parent
c3d429ddd8
commit
a69f6240cc
2 changed files with 16 additions and 13 deletions
|
@ -5,10 +5,10 @@
|
|||
`lambda` expressions can be defined without any parameters.
|
||||
|
||||
```py
|
||||
reveal_type(lambda: 1) # revealed: () -> @Todo(lambda return type)
|
||||
reveal_type(lambda: 1) # revealed: () -> Unknown
|
||||
|
||||
# error: [unresolved-reference]
|
||||
reveal_type(lambda: a) # revealed: () -> @Todo(lambda return type)
|
||||
reveal_type(lambda: a) # revealed: () -> Unknown
|
||||
```
|
||||
|
||||
## With parameters
|
||||
|
@ -17,45 +17,45 @@ Unlike parameters in function definition, the parameters in a `lambda` expressio
|
|||
annotated.
|
||||
|
||||
```py
|
||||
reveal_type(lambda a: a) # revealed: (a) -> @Todo(lambda return type)
|
||||
reveal_type(lambda a, b: a + b) # revealed: (a, b) -> @Todo(lambda return type)
|
||||
reveal_type(lambda a: a) # revealed: (a) -> Unknown
|
||||
reveal_type(lambda a, b: a + b) # revealed: (a, b) -> Unknown
|
||||
```
|
||||
|
||||
But, it can have default values:
|
||||
|
||||
```py
|
||||
reveal_type(lambda a=1: a) # revealed: (a=Literal[1]) -> @Todo(lambda return type)
|
||||
reveal_type(lambda a, b=2: a) # revealed: (a, b=Literal[2]) -> @Todo(lambda return type)
|
||||
reveal_type(lambda a=1: a) # revealed: (a=Literal[1]) -> Unknown
|
||||
reveal_type(lambda a, b=2: a) # revealed: (a, b=Literal[2]) -> Unknown
|
||||
```
|
||||
|
||||
And, positional-only parameters:
|
||||
|
||||
```py
|
||||
reveal_type(lambda a, b, /, c: c) # revealed: (a, b, /, c) -> @Todo(lambda return type)
|
||||
reveal_type(lambda a, b, /, c: c) # revealed: (a, b, /, c) -> Unknown
|
||||
```
|
||||
|
||||
And, keyword-only parameters:
|
||||
|
||||
```py
|
||||
reveal_type(lambda a, *, b=2, c: b) # revealed: (a, *, b=Literal[2], c) -> @Todo(lambda return type)
|
||||
reveal_type(lambda a, *, b=2, c: b) # revealed: (a, *, b=Literal[2], c) -> Unknown
|
||||
```
|
||||
|
||||
And, variadic parameter:
|
||||
|
||||
```py
|
||||
reveal_type(lambda *args: args) # revealed: (*args) -> @Todo(lambda return type)
|
||||
reveal_type(lambda *args: args) # revealed: (*args) -> Unknown
|
||||
```
|
||||
|
||||
And, keyword-varidic parameter:
|
||||
|
||||
```py
|
||||
reveal_type(lambda **kwargs: kwargs) # revealed: (**kwargs) -> @Todo(lambda return type)
|
||||
reveal_type(lambda **kwargs: kwargs) # revealed: (**kwargs) -> Unknown
|
||||
```
|
||||
|
||||
Mixing all of them together:
|
||||
|
||||
```py
|
||||
# revealed: (a, b, /, c=Literal[True], *args, *, d=Literal["default"], e=Literal[5], **kwargs) -> @Todo(lambda return type)
|
||||
# revealed: (a, b, /, c=Literal[True], *args, *, d=Literal["default"], e=Literal[5], **kwargs) -> Unknown
|
||||
reveal_type(lambda a, b, /, c=True, *args, d="default", e=5, **kwargs: None)
|
||||
```
|
||||
|
||||
|
@ -96,5 +96,5 @@ Here, a `lambda` expression is used as the default value for a parameter in anot
|
|||
expression.
|
||||
|
||||
```py
|
||||
reveal_type(lambda a=lambda x, y: 0: 2) # revealed: (a=(x, y) -> @Todo(lambda return type)) -> @Todo(lambda return type)
|
||||
reveal_type(lambda a=lambda x, y: 0: 2) # revealed: (a=(x, y) -> Unknown) -> Unknown
|
||||
```
|
||||
|
|
|
@ -3840,9 +3840,12 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||
Parameters::empty()
|
||||
};
|
||||
|
||||
// TODO: Useful inference of a lambda's return type will require a different approach,
|
||||
// which does the inference of the body expression based on arguments at each call site,
|
||||
// rather than eagerly computing a return type without knowing the argument types.
|
||||
Type::Callable(CallableType::General(GeneralCallableType::new(
|
||||
self.db(),
|
||||
Signature::new(parameters, Some(todo_type!("lambda return type"))),
|
||||
Signature::new(parameters, Some(Type::unknown())),
|
||||
)))
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue