[Feat] better behavior for `getattr()` w/ literal attribute names
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 516
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the Bug
Right now `getattr()` returns `Any` when no default is provided and `Any | None` when a default is provided.
the arguments are `object, attr_name, default`
I think we can improve the behavior here with some special casing. If the second argument is a known literal, then we should be able to get a precise type for the attribute instead of returning `Any`.
If the literal does not correspond to a known attribute, then we probably need to return `Any` if the class is not final. If the class is final then we might want to error + return `Never`.
```
from typing import reveal_type
class Foo:
x: int # x is conditionally initialized
def __init__(self):
pass
def set_x(self, x: int):
self.x = x
foo = Foo()
attr_name: str = ""
# right now, getattr always returns `Any` when there is no default
reveal_type(getattr(foo, "x")) # expect `int`
reveal_type(getattr(foo, "y")) # expect `Any`
reveal_type(getattr(foo, attr_name)) # fall back to regular call path, expect `Any | None`
# right now, getattr always returns `Any | None` when there is a default
reveal_type(getattr(foo, "x", None)) # expect `int | None`
reveal_type(getattr(foo, "y", None)) # expect `Any | None`
reveal_type(getattr(foo, attr_name)) # fall back to regular call path, expect `Any | None`
```
For now maybe we can just do this if the first argument is a `Type::ClassType`, but maybe in the future we can get fancier
### Sandbox Link
https://pyrefly.org/sandbox/?project=v2.lVXBboMwDP0Va1xAq5Z7L7vtPGlXpBG1HjChBJEwwr5-dhI2wira3kKIHef5vec7LDPxmSClF60jIu5I3bCQgWMCnrQ6t8EKu5l-0Fp27TeSS1zU3Jp2oS28-jts0L67qKhw0zrCy9ERPC6wQ9OSKmOySGsHTyvvDB5BRq9UGQxt3VhQejpAjZYPguwmOZtIfAMVDYkKpgYV2AYHLy2luSA5drZUK0DymCKn2w90iSsfigIIDnQ9i7eikqvdiHkb4UdKBY_cBQyU3Enw-9A0iX9BmuL2t0fL2UIgb0WAxiJb1RaHJe01OC6Fr6vKyQY-R8NQ8fdz8V-RGbyGDYjkZmZ-tPVIE4_Y-cRYvCFCY21vjkIs4XqoBSpx1icjkggBbD7yS7Z-jqbpQHsHMZR2xwr6AYnOfmvBkfW8J9If
### (Only applicable for extension issues) IDE Information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.