attrs: don't use __annotations__
https://github.com/python-attrs/attrs/blob/aa501176fac1f12912f863fd2f5c4d1d08410322/src/attr/_make.py#L213 uses __annotations__
However, it looks as though an upcoming incompatible change to Python will change __annotations__
into a list of strings.
It seems like the correct public API to use to retrieve the information attrs
wants would be get_type_hints
.
As a bonus, fixing this might make #265 easier to implement.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 37 (34 by maintainers)
So I played around with this for a while and came to the following conclusion. attrs should probably use
__annotations__
but have a way to resolve the types to real types if needed.The real issue is there’s no way to guarantee that
typing.get_type_hints()
won’t fail. And about 90% of the time you don’t need it. (Technically you need the type for ClassVar but I would just check for “ClassVar” or “typing.ClassVar”)I found three places where you can call
typing.get_type_hints()
At class creation time. This will work find if there are no forward or self references on the class. Otherwise NameError. (I believe you can hack something to make self references work, by passing {cls.name: cls} to localns.)
When a class is instantiated (for example by adding something to init) this works fine for self references and most forward references. Except it won’t work if those types are defined in
if TYPE_CHECKING:
sections.Here’s the code to resolve_types: I believe caching is useful because typing.get_type_hints can be somewhat slow. I don’t know how y’all feel about hanging something off the class.
This was how I modified _get_annotations to get them at class creation time:
And this is how I check them at instance creation time, by adding it to the generated init.
❤️❤️❤️
I’m very confused. They want to remove
typing
, but…we have to usetyping.get_type_hints()
so things keep working!?Why am I already regretting ever supporting this half-baked bullshit? 😢
So I guess I should add support to cattrs for this? I wonder if there’s comprehensive docs anywhere for tools that use runtime types that would help me adjust. Are we just supposed to call get_type_hints() if we encounter a string type? Is that going to be super slow if we do it on every single use?
TBH I feel like the Python typing crowd kinda looks down on using types in runtime, which is amusing because runtime types are several orders of magnitude more useful to me at this point than running mypy over my codebases (which remains borderline useless). My codebases simply wouldn’t work at all without runtime types, and the alternatives are much, much uglier and less user-friendly.
No open source maintenance best open source maintenance.
I think so.