gh-133684: Fix get_annotations() where PEP 563 is involved (#133795)

This commit is contained in:
Jelle Zijlstra 2025-05-25 08:40:58 -07:00 committed by GitHub
parent 4443110c34
commit 3e562b3942
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 84 additions and 4 deletions

View file

@ -1042,14 +1042,27 @@ def _get_and_call_annotate(obj, format):
return None
_BASE_GET_ANNOTATIONS = type.__dict__["__annotations__"].__get__
def _get_dunder_annotations(obj):
"""Return the annotations for an object, checking that it is a dictionary.
Does not return a fresh dictionary.
"""
ann = getattr(obj, "__annotations__", None)
if ann is None:
return None
# This special case is needed to support types defined under
# from __future__ import annotations, where accessing the __annotations__
# attribute directly might return annotations for the wrong class.
if isinstance(obj, type):
try:
ann = _BASE_GET_ANNOTATIONS(obj)
except AttributeError:
# For static types, the descriptor raises AttributeError.
return None
else:
ann = getattr(obj, "__annotations__", None)
if ann is None:
return None
if not isinstance(ann, dict):
raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")