Message391824
> Functions don't store __annotations__ in their __dict__, it is a
> separate slot named func_annotations (see funcobject.c). I guess
> that's because the __dict__ is purely for user-defined function
> attributes.
I brought up functions because I'm now proposing to make classes and modules behave more like functions in this one way, that they too will now lazy-create an empty annotations dict every time. But yes, function objects don't store __annotations__ in their __dict__, and best practices for 3.9 and before was to use fn.__annotations__ or getattr() when getting the annotations from a function object, and 3.10 will not change that best practice.
I don't know specifically why the implementor made that design choice, but I might have done that too. Most function objects don't have a __dict__ so this is almost always cheaper overall. And recreating the dict seems harmless.
(Just to round the bases on this topic: I don't think you should be permitted to delete __annotations__, like most other metadata items on functions / classes / modules. But I don't propose to change that for 3.10.)
> So if you look in __dict__ it will be like it's still Python 3.9,
> but if you're using the attribute (the recommended approach for code
> that only cares about 3.10) it'll be as if it always existed. Sounds
> pretty compatible to me.
Yes, exactly. That was the thing I finally figured out this afternoon. Sorry for being a slow learner.
Again, this approach will change the semantics around deleting annotations on class and module objects. Deleting them won't be permanent--if you delete one, then ask for it, a fresh one will be created. But that seems harmless.
> So, honestly I don't understand what your concern with the lazy
> approach is. Was your design based on having a bit in the
> class/module object (outside its __dict__) saying "I already
> lazily created one"? Or am I missing something?
My concern is that always lazy-creating on demand will change user-visible behavior. Consider this code:
class C:
a:int=3
del C.__annotations__
print(C.__annotations__)
In 3.9, that throws an AttributeError, because C no longer has an '__annotations__' attribute. If I change Python 3.10 so that classes and modules *always* lazy-create __annotations__ if they don't have them, then this code will succeed and print an empty dict.
That's a user-visible change, and I was hoping to avoid those entirely. Is it a breaking change? I doubt it. Is it an important change? It doesn't seem like it. I bring it up just in the interests of considering every angle. But I don't think this is important at all, and I think always lazy-creating annotations dicts on classes and modules is the right approach. |
|
Date |
User |
Action |
Args |
2021-04-24 23:51:50 | larry | set | recipients:
+ larry, gvanrossum, eric.smith, Guido.van.Rossum |
2021-04-24 23:51:50 | larry | set | messageid: <1619308310.62.0.059162629675.issue43901@roundup.psfhosted.org> |
2021-04-24 23:51:50 | larry | link | issue43901 messages |
2021-04-24 23:51:49 | larry | create | |
|