I think your analysis of the problems is great. I don't worry about people deleting `__attributes__` (and those that do can switch to calling its .clear() method instead) but I worry about people not expecting to get None. So if you can avoid that in your solution that would be great. The easiest thing would be just to create an empty `__annotations__` for classes that have no annotated variables, and to hell with the cost. People who delete it are already living dangerously.

(I noticed that `__slots__` is missing from your list. Maybe because it follows yet another pattern?)

On Mon, Jan 11, 2021 at 4:07 PM Larry Hastings <larry@hastings.org> wrote:

At last, a nibble on the other fishing line! ;-)

On 1/11/21 1:47 PM, Brett Cannon wrote:
So the biggest potential breakages are code that:
  1. Directly get the attribute from __dict__
  2. The fact that it would no longer be inherited
Am I missing anything else?

Those are the big ones, the ones I expect people to actually experience.  I can name three more breakages, though these get progressively more obscure:

  • Nobody expect o.__annotations__ to ever be None (unless they assigned None to it themselves).  If the attribute is set they expect its value to be a dict.
  • "del o.__annotations__" currently works on modules and classes if the attribute is set.  "del fn.__annotations__" always works.
  • On modules and classes you can set o.__annotations__ to any Python value.  (Functions already only permit you to set it to None or a dict.)

I have no idea if anybody is depending on these behaviors.  The lesson that years of Python core dev has taught me is: if Python exhibits a behavior, somebody out there depends on it, and you'll break their code if you change it.  Or, expressed more succinctly, any change is a breaking change for somebody.  So the question is, is the improvement this brings worth the breakage it also brings?  In this case, I sure hope so!

For issue #2, if the default was `None`, then couldn't that be used as an implicit feature marker that you can't (incorrectly) rely on inheritance to percolate up the annotations of the superclass if the subclass happens to not define any annotations?

Currently Python never sets o.__annotations__ to None on any object.  So yes, assuming the user doesn't set it to None themselves, this would be new behavior.  If I understand your question correctly, yes, users could write new code that says

if o.__annotations__ is None:
    # great, we're in Python 3.10+ and no annotation was set on o!

Or they could just look at sys.version_info ;-)

Thanks for your feedback,


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

--Guido van Rossum (python.org/~guido)
Pronouns: he/him (why is my pronoun here?)