Commits
Click on a commit to change the comparison range[ty] Support calls to intersection types
Implement proper handling for calling intersection types. Previously,
calling an intersection type would return a `@Todo` type that suppressed
errors but provided no useful type information.
Now, when calling an intersection type:
- We try to call each positive element with the given arguments
- Elements where the call fails (wrong arguments, not callable, etc.)
are discarded
- If at least one element succeeds, the call is valid
- The return type is the intersection of return types from successful
elements
- If all elements fail, an appropriate error is reported
This approach means that if an intersection contains both a callable
with a known signature and a `Top[Callable[..., object]]` (from
narrowing by `callable()`), the call will succeed using the element
with the known signature, avoiding spurious `call-top-callable` errors.
Fixes https://github.com/astral-sh/ty/issues/1858 Fix markdown formatting in intersection_types.md [ty] Show individual errors when all intersection elements fail a call
When calling an intersection type where all callable elements reject
the specific call arguments, we now show an error for each failing
element (similar to how unions work) instead of a single generic
"not callable" error.
This is achieved by:
- Not filtering out failed elements when ALL elements fail
- Returning BindingError instead of NotCallable to trigger individual diagnostics
- Adding IntersectionDiagnostic struct and CompoundDiagnostic trait
- Modifying report_diagnostics to iterate over intersection elements Bump sympy expected diagnostics to 13200
More diagnostics are now emitted due to showing individual errors
when all intersection elements fail a call. [ty] Add priority hierarchy for intersection call errors
When all intersection elements fail a call, we now use a priority
hierarchy to determine which errors to show:
1. NotCallable (lowest) - object has no __call__ method
2. TopCallable - object is a top callable with unknown signature
3. BindingError (highest) - specific errors like invalid-argument-type
Only errors from the highest priority category are shown. This prevents
noise from less-specific errors when more informative errors are available.
For example, if an intersection has one element that fails with
invalid-argument-type and another that's not callable, we only show
the invalid-argument-type error since it's more specific and actionable. [ty] Support unions containing intersection elements in call bindings
Refactors the `Bindings` structure to use a two-level representation:
- Outer level: union elements (each can be a single callable or an intersection)
- Inner level: bindings within an intersection element
This enables proper handling of types like `(A & B) | C` when calling,
where `A & B` is an intersection that was narrowed by `callable()`.
Key changes:
- Add `BindingsElement` struct to represent a single union element
(which may contain multiple bindings for intersections)
- Update `from_union` to preserve intersection structure instead of
flattening
- Update `from_intersection` to create a single element with multiple
bindings
- Update `return_type`, `check_types_impl`, and `report_diagnostics`
to handle the two-level structure
- Add test for union-of-intersections case
The priority hierarchy for intersection call errors is preserved: when
all bindings in an intersection fail, only the highest-priority error
type is reported (BindingError > TopCallable > NotCallable). Merge main into claude/fix-issue-1858-UjARA
Resolves conflicts between the two-level Bindings structure and
main's new Type match cases for property descriptors, dataclass
transformers, and other features. Bump freqtrade expected diagnostics from 600 to 650 Fix invalid-await for intersections containing dynamic types
This PR fixes false `invalid-await` errors for patterns like:
```python
if inspect.isawaitable(x):
await x # x has type Unknown & Awaitable[object]
```
Changes:
1. Add intersection handling to `generator_return_type()` so that await
operations on intersection types work correctly. When awaiting an
intersection, we iterate over positive elements, collect return types
from awaitable elements, and intersect them together. Non-awaitable
elements are skipped; only if all elements fail to be awaitable do we
report an error.
2. Add intersection handling to `try_call_dunder_with_policy()` to call
dunder methods on each intersection element separately and combine the
results. This avoids intersecting bound methods (which often collapses
to Never) and instead intersects the return types.
Added tests for:
- Awaiting `Unknown & Awaitable[object]` returns `Unknown`
- Awaiting intersection of two Coroutine types
- Awaiting intersection with non-awaitable elements skips those elements
- Awaiting intersection where all elements are non-awaitable produces error Refactor dataclass params to use with_dataclass_params helper
Simplify the code by using the with_dataclass_params method instead
of manually constructing a new ClassLiteral with all parameters. Remove unused ClassLiteral import
The import is no longer needed after refactoring to use
with_dataclass_params helper method. Fix dataclass transform function handling after merge
- Fix test expectations in dataclasses.md to match main's expected output
- Restore full dataclass_transform decorated function handling logic that
was lost during merge - this includes the heuristics to detect whether
a decorated function is being used as a direct decorator or as a
decorator factory based on positional arguments and return type
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>