[ty] Restrict length narrowing to types that encode their length (#25840)
## Summary
Restrict exact `len()` narrowing to types that actually encode their
possible lengths, so that we don't wrongly preserve length-narrowings on
types with mutable length.
Closes astral-sh/ty#3710.
## Test plan
Added/updated mdtests.
### Ecosystem analysis
72 of the added diagnostics (48 in apprise, 19 in scrapy, plus some
others) are from restoring correct reachability to code that was
previously erroneously marked unreachable.
33 new diagnostics involve cases where we previously narrowed `None` out
of a type after a `len` call (which itself errors since `None` is not
`Sized`), since `None` is disjoint from `ExactlySized`. We could easily
continue to do this (remove any non `Sized` types when narrowing from a
`len` check), and I don't think it's wrong to do so? But it's kind of
odd to narrow from a failed call, and no other type checker does it, so
I haven't done it in this PR.
12 new diagnostics (all in packaging, or pip from its vendored
packaging) come from a case where we are length-narrowing correctly,
it's just we top-materialize `isinstance` and `object` is not assignable
where a value from that tuple is used. This was silenced on main because
we don't support exact unpacking from an intersection at all, and we
previously had an intersection with `ExactlySized` here.
Four new diagnostics in `ppb-vector` come from code like this:
```py
def unpack(value: Sequence[int] | Mapping[str, int]):
if isinstance(value, Sequence) and len(value) == 2:
return value[0]
if isinstance(value, Mapping) and "x" in value and len(value) == 2:
return value["x"]
raise ValueError
```
Where retaining the intersection with `~ExactlySized[2]` allowed us to
rule out the "both a Sequence and a Mapping" case in the second branch
(since if it were a sequence of length 2 it would have already taken the
first branch). This is the only case where this PR regresses results. We
could keep this by restoring `ExactlySized` and continuing to use it
with `Sequence` and `Mapping` types -- but that would add a lot of code
for something that has a very small ecosystem impact.