Skip to content

Conversation

@JelleZijlstra
Copy link
Member

@JelleZijlstra JelleZijlstra commented Apr 10, 2025

This fixes #132261 and provides a more elegant solution for https://peps.python.org/pep-0749/#annotations-and-metaclasses. The trouble is that we store things at the __annotate__ and __annotations__ keys in the class dictionary and they interfere with the descriptors on type: the solution is to not store our internal objects at those keys. Instead, we now store the annotate function at __annotate_func__ and the annotations dict (once evaluated) at __annotations_cache__. These names remain undocumented implementation details.

Downsides:

  • If you look at the class dict, you'll see those new keys. typing.py needed some updates to deal with this.
  • The compatibility store with 3.13 changes in regards to looking directly in the class namespace for __annotations__. In 3.13, this always worked: if a class has annotations there's an __annotations__ key in the class dict. On current main, it sometimes works (only if somebody has accessed the .__annotations__ attribute). With this PR, it never works (unless the __annotations__ key was explicitly added). Breaking this pattern consistently seems better than breaking it nondeterministically though.
  • It becomes harder to get the annotate function in a metaclass __new__. I made annotationlib.get_annotate_function() handle this.
  • The internal names become accessible as attributes (e.g. you can do cls.__annotate_func__).

📚 Documentation preview 📚: https://cpython-previews--132345.org.readthedocs.build/

@JelleZijlstra JelleZijlstra requested a review from Eclips4 as a code owner April 10, 2025 14:22
Copy link
Member

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty good to me! I expected it to be a lot gnarlier. It really just removes the ugly special handling of class annotations, everything it adds looks predictable and reasonably straightforward.

Thanks for your work on this!

@JelleZijlstra JelleZijlstra merged commit 07b8d31 into python:main Apr 11, 2025
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[3.14] annotationlib - calling get_annotations on instances gets an unexpected error

2 participants