[ty] Add disjointness for protocol method members (#25315)
## Summary
This PR implements disjointness checking for protocols with method
members by comparing non-`Never` return types, e.g., we now understand
that a fixed-length tuple whose synthesized `__len__` returns
`Literal[3]` is disjoint from a protocol requiring `__len__` to return
`Literal[2]`:
```python
from typing import Literal, Protocol
from ty_extensions import is_disjoint_from, static_assert
class HasLengthTwo(Protocol):
def __len__(self) -> Literal[2]: ...
static_assert(is_disjoint_from(tuple[int, int, int], HasLengthTwo))
```
This is a prerequisite for using synthesized exact-length protocols to
narrow unions of fixed-length tuples and sequence patterns (see:
https://github.com/astral-sh/ruff/pull/22134#issuecomment-4517932605).
Per that comment, this isn't fully sound: a subclass can override an
otherwise incompatible method with a `Never`-returning implementation
and therefore inhabit both types that we infer to be disjoint. C
Charlie Marsh committed
dba3619fb385289cd43705609708efc0230ea6a6
Parent: 6d2ca1a
Committed by GitHub <noreply@github.com>
on 5/30/2026, 3:25:45 PM