Larry Hastings <la...@hastings.org> added the comment:
> 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. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue43901> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com