aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/annotationlib.py
diff options
context:
space:
mode:
authorJelle Zijlstra <jelle.zijlstra@gmail.com>2025-04-16 06:16:13 -0700
committerGitHub <noreply@github.com>2025-04-16 06:16:13 -0700
commita8ca26d250a3eedbb629fc19e40b7de6774f05a5 (patch)
treef9308eb86584d8d22f64d91b3223cd71a80df055 /Lib/annotationlib.py
parentc35c7353eb8fbccff2d3a6ab664426b31af00d4d (diff)
downloadcpython-a8ca26d250a3eedbb629fc19e40b7de6774f05a5.tar.gz
cpython-a8ca26d250a3eedbb629fc19e40b7de6774f05a5.zip
annotationlib: Remove some unnecessary dict copies (#132495)
Diffstat (limited to 'Lib/annotationlib.py')
-rw-r--r--Lib/annotationlib.py34
1 files changed, 19 insertions, 15 deletions
diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py
index 322b6ded2b3..2acd33b1e48 100644
--- a/Lib/annotationlib.py
+++ b/Lib/annotationlib.py
@@ -716,11 +716,11 @@ def get_annotations(
# For STRING, we try to call __annotate__
ann = _get_and_call_annotate(obj, format)
if ann is not None:
- return ann
+ return dict(ann)
# But if we didn't get it, we use __annotations__ instead.
ann = _get_dunder_annotations(obj)
if ann is not None:
- ann = annotations_to_string(ann)
+ return annotations_to_string(ann)
case Format.VALUE_WITH_FAKE_GLOBALS:
raise ValueError("The VALUE_WITH_FAKE_GLOBALS format is for internal use only")
case _:
@@ -813,7 +813,10 @@ def type_repr(value):
def annotations_to_string(annotations):
- """Convert an annotation dict containing values to approximately the STRING format."""
+ """Convert an annotation dict containing values to approximately the STRING format.
+
+ Always returns a fresh a dictionary.
+ """
return {
n: t if isinstance(t, str) else type_repr(t)
for n, t in annotations.items()
@@ -821,27 +824,28 @@ def annotations_to_string(annotations):
def _get_and_call_annotate(obj, format):
+ """Get the __annotate__ function and call it.
+
+ May not return a fresh dictionary.
+ """
annotate = get_annotate_function(obj)
if annotate is not None:
ann = call_annotate_function(annotate, format, owner=obj)
if not isinstance(ann, dict):
raise ValueError(f"{obj!r}.__annotate__ returned a non-dict")
- return dict(ann)
+ return ann
return None
def _get_dunder_annotations(obj):
- if isinstance(obj, type):
- try:
- ann = obj.__annotations__
- except AttributeError:
- # For static types, the descriptor raises AttributeError.
- return None
- else:
- ann = getattr(obj, "__annotations__", None)
- if ann is None:
- return None
+ """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
if not isinstance(ann, dict):
raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")
- return dict(ann)
+ return ann