PEP 749: Implementing PEP 649

I ran into a few interrelated bugs with the current implementation:

>>> class X(type):
...     a: int
...     
>>> class Y(metaclass=X):
...     b: str
...     
>>> X.__annotations__
{'a': <class 'int'>}
>>> Y.__annotations__
{'a': <class 'int'>}

Accessing the annotations on the metaclass caches them in the metaclass’s __dict__, and subsequently, lookups on classes that are instances of the metaclass return the metaclass’s annotations.

And if the class itself doesn’t have any annotations:

>>> class X(type):
...     a: int
...     
>>> class Y(metaclass=X): pass
... 
>>> Y.__annotate__
<bound method X.__annotate__ of <class '__main__.Y'>>

Instead, Y.__annotate__ should be None.

I’ve stared at this problem for a while now and I’m not sure what to do about it yet; I’d appreciate any opinions.

I’ll note that some related behavior is also buggy on existing versions (this is 3.12.2):

>>> class X(type):
...     a: int
... 
>>> class Y(metaclass=X): pass
... 
>>> Y.__annotations__
{'a': <class 'int'>}