ruff
bab688b7 - [ty] Retain the function-like-ness of `Callable` types when binding `self` (#21614)

Commit
91 days ago
[ty] Retain the function-like-ness of `Callable` types when binding `self` (#21614) ## Summary For something like this: ```py from typing import Callable def my_lossy_decorator(fn: Callable[..., int]) -> Callable[..., int]: return fn class MyClass: @my_lossy_decorator def method(self) -> int: return 42 ``` we will currently infer the type of `MyClass.method` as a function-like `Callable`, but we will infer the type of `MyClass().method` as a `Callable` that is _not_ function-like. That's because a `CallableType` currently "forgets" whether it was function-like or not during the `bound_self` transformation: https://github.com/astral-sh/ruff/blob/a57e29131125bf05db7379e90c7616eec32624fe/crates/ty_python_semantic/src/types.rs#L10985-L10987 This seems incorrect, and it's quite different to what we do when binding the `self` parameter of `FunctionLiteral` types: `BoundMethod` types are all seen as subtypes of function-like `Callable` supertypes -- here's `BoundMethodType::into_callable_type`: https://github.com/astral-sh/ruff/blob/a57e29131125bf05db7379e90c7616eec32624fe/crates/ty_python_semantic/src/types.rs#L10844-L10860 The bug here is also causing lots of false positives in the ecosystem report on https://github.com/astral-sh/ruff/pull/21611: a decorated method on a subclass is currently not seen as validly overriding an undecorated method with the same signature on a superclass, because the undecorated superclass method is seen as function-like after binding `self` whereas the decorated subclass method is not. Fixing the bug required adding a new API in `protocol_class.rs`, because it turns out that for our purposes in protocol subtyping/assignability, we really do want a callable type to forget its function-like-ness when binding `self`. I initially tried out this change without changing anything in `protocol_class.rs`. However, it resulted in many ecosystem false positives and new false positives on the typing conformance test suite. This is because it would mean that no protocol with a `__call__` method would ever be seen as a subtype of a `Callable` type, since the `__call__` method on the protocol would be seen as being function-like whereas the `Callable` type would not be seen as function-like. ## Test Plan Added an mdtest that fails on `main`
Author
Parents
Loading