On 1/16/21 8:41 AM, Nick Coghlan wrote:
Could you get the best of both worlds by making __annotations__ an auto-populating descriptor on "type", the way it is on functions?

Continue to add a non-empty annotations dict to the class dict eagerly, but only add the empty dict when "cls.__annotations__" is accessed.


I think that'll work though it's a little imprecise.  Consider the best practice for getting class annotations, example here from Lib/dataclasses.py:

   cls_annotations = cls.__dict__.get('__annotations__', {})

What happens when that current best practice code meets your proposed "lazy-populate the empty dict" approach?

 * If a class has annotations set, cls.__dict__['__annotations__'] will
   be set, so the code works fine.

 * If a class doesn't have annotations set, then
   cls.__dict__['__annotations__'] won't be set yet.  So people peering
   in cls.__dict__['__annotations__'] will get the right /answer/, that
   no annotations are set.  But they'll see the wrong /specifics/:
   they'll think annotations are unset, when in fact it has an empty
   dict as its value.

So the code will continue to work, even though it's arguably a little misguided.  If anybody distinguished between "annotations are unset" and "annotations are set to an empty dict", that code would fail, but I expect nobody ever does that.

Two notes about this idea.  First, I think most people who use this best-practices code above use it for modules as well as classes.  (They have two code paths: one for functions, the other for not-functions.)  But everything I said above is true for both classes and modules.

Second, I think this is only sensible if, at the same time, we make it illegal to delete cls.__annotations__.  If we lazy-populate the empty dict, and a user deletes cls.__annotations__, and we don't remember some extra state, we'd just re-"lazy" create the empty dict the next time they asked for it.  Which is actually what functions do, just lazy-repopulate the empty annotations dict every time, and I'm not keen to bring those semantics to classes and modules.


Cheers,


//arry/

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/XNJWBEYSAPMBMNCUUK7MWH2L6HNBST3Z/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to