mirror of
https://github.com/astral-sh/ruff
synced 2026-01-21 21:40:51 -05:00
## Summary A couple things I noticed when taking another look at the callable type materializations. 1) Previously we wrongly ignored the return type when bottom-materializing a callable with gradual signature, and always changed it to `Never`. 2) We weren't correctly handling overloads that included a gradual signature. Rather than separately materializing each overload, we would just mark the entire callable as "top" or replace the entire callable with the bottom signature. Really, "top parameters" is something that belongs on the `Parameters`, not on the entire `CallableType`. Conveniently, we already have `ParametersKind` where we can track this, right next to where we already track `ParametersKind::Gradual`. This saves a bit of memory, fixes the two bugs above, and simplifies the implementation considerably (net removal of 100+ LOC, a bunch of places that shouldn't need to care about topness of a callable no longer need to.) One user-visible change from this is that I now display the "top callable" as `(Top[...]) -> object` instead of `Top[(...) -> object]`. I think this is a (minor) improvement, because it wraps exactly the part in `Top` that needs to be, rather than misleadingly wrapping the entire callable type, including the return type (which has already been separately materialized). I think the prior display would be particularly confusing if the return type also has its own `Top` in it: previously we could have e.g. `Top[(...) -> Top[list[Unknown]]]`, which I think is less clear than the new `(Top[...]) -> Top[list[Unknown]]`. ## Test Plan Added mdtests that failed before this PR and pass after it. ### Ecosystem The changed diagnostics are all either the change to `Top` display, or else known non-deterministic output. The added diagnostics are all true positives: The added diagnostic ataa35ca1965/torchvision/transforms/v2/_utils.py (L149)is a true positive that wasn't caught by the previous version. `str` is not assignable to `Callable[[Any], Any]` (strings are not callable), nor is the top callable (top callable includes callables that do not take a single required positional argument.) The added diagnostic at081535ad9b/starlette/routing.py (L67)is also a (pedantic) true positive. It's the same case as #1567 -- the code assumes that it is impossible for a subclass of `Response` to implement `__await__` (yielding something other than a `Response`). The pytest added diagnostics are also both similar true positives: they make the assumption that an object cannot simultaneously be a `Sequence` and callable, or an `Iterable` and callable.