[ty] Preserve literal enum member names (#26592)
## Summary
When we cannot determine whether an enum declaration is an alias, we
currently widen its `.name` attribute to `str`. This regressed `IntEnum`
and `StrEnum` classes with custom `__new__` methods or enum metaclasses
in ty 0.0.56, even though the declaration name is preserved in the
common case:
```python
class Medal(IntEnum):
def __new__(cls, value: int) -> "Medal":
obj = int.__new__(cls, value)
obj._value_ = value
return obj
GOLD = auto()
reveal_type(Medal.GOLD.name) # Literal["GOLD"], previously str
```
A custom constructor or metaclass can technically make a declaration an
alias of another member, in which case using the declaration spelling is
unsound. But we'll now accept that limitation -- it matches Pyright and
other type checkers in #3923, avoids surprising differences between
otherwise similar enum definitions, and favors the overwhelmingly common
case where construction does not create aliases.
When alias detection is precise, we continue to return the canonical
member name. The relaxed behavior applies only when the canonical name
is unknown, with regression coverage for custom `__new__`, uncertain
built-in coercion, user-defined data-type mixins, and transforming enum
metaclasses.
Closes https://github.com/astral-sh/ty/issues/3923.