mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +00:00
[red-knot] Assignability of class instances to Callable (#17590)
## Summary Model assignability of class instances with a `__call__` method to `Callable` types. This should solve some false positives related to `functools.partial` (yes, 1098 fewer diagnostics!). Reference: https://github.com/astral-sh/ruff/issues/17343#issuecomment-2824618483 ## Test Plan New Markdown tests.
This commit is contained in:
parent
e170fe493d
commit
61e73481fe
2 changed files with 36 additions and 0 deletions
|
@ -560,4 +560,30 @@ c: Callable[..., int] = overloaded
|
|||
c: Callable[[int], str] = overloaded
|
||||
```
|
||||
|
||||
### Classes with `__call__`
|
||||
|
||||
```py
|
||||
from typing import Callable, Any
|
||||
from knot_extensions import static_assert, is_assignable_to
|
||||
|
||||
class TakesAny:
|
||||
def __call__(self, a: Any) -> str:
|
||||
return ""
|
||||
|
||||
class ReturnsAny:
|
||||
def __call__(self, a: str) -> Any: ...
|
||||
|
||||
static_assert(is_assignable_to(TakesAny, Callable[[int], str]))
|
||||
static_assert(not is_assignable_to(TakesAny, Callable[[int], int]))
|
||||
|
||||
static_assert(is_assignable_to(ReturnsAny, Callable[[str], int]))
|
||||
static_assert(not is_assignable_to(ReturnsAny, Callable[[int], int]))
|
||||
|
||||
from functools import partial
|
||||
|
||||
def f(x: int, y: str) -> None: ...
|
||||
|
||||
c1: Callable[[int], None] = partial(f, y="a")
|
||||
```
|
||||
|
||||
[typing documentation]: https://typing.python.org/en/latest/spec/concepts.html#the-assignable-to-or-consistent-subtyping-relation
|
||||
|
|
|
@ -1460,6 +1460,16 @@ impl<'db> Type<'db> {
|
|||
self_callable.is_assignable_to(db, target_callable)
|
||||
}
|
||||
|
||||
(Type::Instance(_), Type::Callable(_)) => {
|
||||
let call_symbol = self.member(db, "__call__").symbol;
|
||||
match call_symbol {
|
||||
Symbol::Type(Type::BoundMethod(call_function), _) => call_function
|
||||
.into_callable_type(db)
|
||||
.is_assignable_to(db, target),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
(Type::FunctionLiteral(self_function_literal), Type::Callable(_)) => {
|
||||
self_function_literal
|
||||
.into_callable_type(db)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue