mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-11 12:56:38 +00:00
[red-knot] Assignability of class instances to Callable (#17590)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## 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
|
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
|
[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)
|
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(_)) => {
|
(Type::FunctionLiteral(self_function_literal), Type::Callable(_)) => {
|
||||||
self_function_literal
|
self_function_literal
|
||||||
.into_callable_type(db)
|
.into_callable_type(db)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue