Latest Results
[ty] Prefer static constrained TypeVar solutions (#27057)
## Summary
Follow-up to [#26965](https://github.com/astral-sh/ruff/pull/26965).
After accepting gradual constrained-TypeVar solutions, a gradual
constraint can match before a more-specific constraint. The existing
subtype-based tie-breaker cannot order these candidates, so inference
depends on declaration order and can discard members of the concrete
type:
```py
from typing import Any, TypeVar
class Row(tuple[Any, ...]):
def asDict(self) -> dict[str, Any]: ...
RowLike = TypeVar("RowLike", list[Any], tuple[Any, ...], Row)
def identity(value: RowLike) -> RowLike: ...
result = identity(Row())
result.asDict() # Previously: unresolved-attribute on tuple[Any, ...]
```
We now compare compatible constraints using assignability. When only one
direction is assignable, lower-bound inference prefers the more-specific
constraint and upper-bound-only inference preserves its existing
preference for the more-general one. When both directions are
assignable, we prefer a fully static constraint over a gradual
constraint, which also makes `TypeVar("T", Any, int)` select `int` for a
concrete integer argument. Incomparable constraints retain declaration
order. Latest Branches
0%
charlie/callable-protocol-receiver-overloads 0%
cjm/4100-tagged-union-intersections 0%
jesco-absolut:fix-20698-pt018-fix-safety © 2026 CodSpeed Technology