
OK. Makes sense to think of __annotations__ as being the location of the final, stable, "affixed" type hints. I wonder if then the __co_annotations__ call and overwriting of __annotations__ should be explicitly caused by a to get_type_hints instead of (mysteriously) occurring on an attempt to getattr __annotations__. I know this changes the descriptor behavior you documented, but at least it would occur explicitly in a function call and may be easier for developers to reason about? It would also address my other question of trying to access __annotations__, only to be confronted with an exception raised within __co_annotations__. On Fri, 2021-01-15 at 09:47 -0800, Larry Hastings wrote:
On 1/11/21 6:34 PM, Paul Bryan wrote:
On Mon, 2021-01-11 at 17:56 -0800, Larry Hastings wrote:
On 1/11/21 5:02 PM, Paul Bryan wrote:
I'm probably naive, but is there a reason that one could not just store a callable in __annotations__, and use the descriptor to resolve it to a dictionary and store it when it is accessed? It would be one less dunder in the Python data model. That would work, but I think the API is a bit of a code smell. __annotations__ would no longer be stable:
a.__annotations__ = o assert a.__annotations__ == o Would that assert fail? It depends on what type(o) is, which is surprising.
Equally surprising?:
a.__co_annotations__ = o a.__annotations__ assert a.__co_annotations__ == o
I've ruminated about this a bit over the past few days, and I finally realized exactly why, yes, I think behavior is more surprising. It's because __annotations__ is now 12 years old (!), and never in that entire time has it silently changed its value. It's always been completely stable, and we have twelve years' worth of installed base that may rely on that assumption. In comparison, __co_annotations__ is a new attribute. While it's also surprising that __co_annotations__ can be automatically unset, at least this would be a documented part of its behavior from day 1. Relatedly, __co_annotations__ is behaving somewhat like a cached value, in that cached values get deleted when they're out-of-date. (An observation that may provide some guidance if we decide to rename __co_annotations__.) This idiom may be familiar to the user--unlike your proposed semantics, which I don't recall ever seeing used in an API. I admit it's only a small difference between what you proposed and what I propose, but in the end I definitely prefer my approach. Cheers,
/arry