Latest Results
[ty] relax the attribute narrowing condition (#22440)
## Summary
Fixes https://github.com/astral-sh/ty/issues/2134
This PR is based on the "pragmatism" that narrowing should only be
disabled when an attribute *is a* data descriptor, and should be left as
is when it *might be a* data descriptor.
I believe this is somewhat justified given the fact that the current
behavior is not strictly safe either.
```python
from typing import Any
class FixedAge:
def __get__(self, obj, objtype=None):
return -1
def __set__(self, obj, value):
pass
class Person:
def __init__(self, age):
self.age = age
class Dead(Person):
age = FixedAge()
def f(p: Person):
p.age = 21
reveal_type(p.age) # reveals Literal[21], but -1 at runtime
f(Dead(20))
```
This code doesn't throw an error, and there's nothing inherently unsound
about it, but the narrowing result is still incorrect.
Even if the class attribute is `Undefined`, there is the possibility of
dynamic attribute additions or additions in subclasses (and this issue
persists even if we don't mark implicit attribute types with `Unknown
|`).
But if we take this into account, this kind of narrowing of implicit
attributes becomes completely inapplicable!
I'd like to see the results of mypy_primer and decide whether this idea
makes sense.
## Test Plan
mdtest updated
---------
Co-authored-by: Carl Meyer <carl@oddbird.net>
Co-authored-by: Carl Meyer <carl@astral.sh> Active Branches
#228440%
#231030%
#231100%
© 2026 CodSpeed Technology