gh-132426: Add get_annotate_from_class_namespace replacing get_annotate_function (#132490)

As noted on the issue, making get_annotate_function() support both types and
mappings is problematic because one object may be both. So let's add a new one
that works with any mapping.

This leaves get_annotate_function() not very useful, so remove it.
This commit is contained in:
Jelle Zijlstra 2025-05-04 07:26:42 -07:00 committed by GitHub
parent 5a57248b22
commit 7cb86c5def
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 136 additions and 65 deletions

View file

@ -12,7 +12,7 @@ __all__ = [
"ForwardRef",
"call_annotate_function",
"call_evaluate_function",
"get_annotate_function",
"get_annotate_from_class_namespace",
"get_annotations",
"annotations_to_string",
"type_repr",
@ -619,20 +619,16 @@ def call_annotate_function(annotate, format, *, owner=None, _is_evaluate=False):
raise ValueError(f"Invalid format: {format!r}")
def get_annotate_function(obj):
"""Get the __annotate__ function for an object.
def get_annotate_from_class_namespace(obj):
"""Retrieve the annotate function from a class namespace dictionary.
obj may be a function, class, or module, or a user-defined type with
an `__annotate__` attribute.
Returns the __annotate__ function or None.
Return None if the namespace does not contain an annotate function.
This is useful in metaclass ``__new__`` methods to retrieve the annotate function.
"""
if isinstance(obj, dict):
try:
return obj["__annotate__"]
except KeyError:
return obj.get("__annotate_func__", None)
return getattr(obj, "__annotate__", None)
try:
return obj["__annotate__"]
except KeyError:
return obj.get("__annotate_func__", None)
def get_annotations(
@ -832,7 +828,7 @@ def _get_and_call_annotate(obj, format):
May not return a fresh dictionary.
"""
annotate = get_annotate_function(obj)
annotate = getattr(obj, "__annotate__", None)
if annotate is not None:
ann = call_annotate_function(annotate, format, owner=obj)
if not isinstance(ann, dict):