[ty] Fix MRO ordering for generic bases (#28172)
## Summary
Previously, mixing gradual and concrete specializations of a generic
base could select an ancestor's method ahead of an override and report a
false `invalid-method-override`:
```python
from typing import Any, reveal_type
class Base[T]:
def method(self) -> object: ...
class Unspecified(Base[Any]): ...
class Concrete(Base[int]):
def method(self) -> int:
return 0
class Child(Unspecified, Concrete): ... # Before: invalid-method-override. After: no error.
reveal_type(Child().method()) # Before: object. After: int.
```
We treated `Base[Any]` and `Base[int]` as distinct classes in the MRO,
placing `Base[Any]` before `Concrete`. We now compare bases by their
underlying class during C3 linearization, while retaining the selected
specialization for member lookup. This puts `Base` after both subclasses
and includes it only once.
Subtype and override checks still consider every inherited
specialization, including those omitted from the MRO used for member
lookup. Fallback MROs use the same class identity for deduplication and
keep `object` last, including when subclasses inherit an inconsistent
MRO.
The relevance of this PR is that it avoids some false positives that
would otherwise be introduced by
https://github.com/astral-sh/ruff/pull/28167, e.g., in [Home
Assistant](https://github.com/home-assistant/core/blob/e4455e962621ad3cd7fbfd9e31a62259ce9c23f1/homeassistant/components/ring/button.py#L34).