https://github.com/python/cpython/commit/96f619faa74a8a32c2c297833cdeb0393c0b6b13
commit: 96f619faa74a8a32c2c297833cdeb0393c0b6b13
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2024-09-18T08:39:22-07:00
summary:

gh-124206: Fix calling get_annotate_function() on static types (#124208)

Fixes #124206. No news entry because the bug this fixes was never
released.

files:
M Lib/annotationlib.py
M Lib/test/test_annotationlib.py
M Lib/test/test_typing.py

diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py
index 9d1943b27e8e9c..09a844ddb56f06 100644
--- a/Lib/annotationlib.py
+++ b/Lib/annotationlib.py
@@ -575,7 +575,11 @@ def get_annotate_function(obj):
     Returns the __annotate__ function or None.
     """
     if isinstance(obj, type):
-        return _BASE_GET_ANNOTATE(obj)
+        try:
+            return _BASE_GET_ANNOTATE(obj)
+        except AttributeError:
+            # AttributeError is raised for static types.
+            return None
     return getattr(obj, "__annotate__", None)
 
 
diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py
index ce4f92624d9036..309f6d2120109a 100644
--- a/Lib/test/test_annotationlib.py
+++ b/Lib/test/test_annotationlib.py
@@ -928,6 +928,27 @@ class D(metaclass=Meta):
                             self.assertIs(annotate_func, None)
 
 
+class TestGetAnnotateFunction(unittest.TestCase):
+    def test_static_class(self):
+        self.assertIsNone(get_annotate_function(object))
+        self.assertIsNone(get_annotate_function(int))
+
+    def test_unannotated_class(self):
+        class C:
+            pass
+
+        self.assertIsNone(get_annotate_function(C))
+
+        D = type("D", (), {})
+        self.assertIsNone(get_annotate_function(D))
+
+    def test_annotated_class(self):
+        class C:
+            a: int
+
+        self.assertEqual(get_annotate_function(C)(Format.VALUE), {"a": int})
+
+
 class TestAnnotationLib(unittest.TestCase):
     def test__all__(self):
         support.check__all__(self, annotationlib)
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 6e036b600330c1..3ac6b97383fcef 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -7043,6 +7043,25 @@ def h(x: collections.abc.Callable[P, int]): ...
         self.assertEqual(get_type_hints(g), {'x': 
collections.abc.Callable[..., int]})
         self.assertEqual(get_type_hints(h), {'x': collections.abc.Callable[P, 
int]})
 
+    def test_get_type_hints_format(self):
+        class C:
+            x: undefined
+
+        with self.assertRaises(NameError):
+            get_type_hints(C)
+
+        with self.assertRaises(NameError):
+            get_type_hints(C, format=annotationlib.Format.VALUE)
+
+        annos = get_type_hints(C, format=annotationlib.Format.FORWARDREF)
+        self.assertIsInstance(annos, dict)
+        self.assertEqual(list(annos), ['x'])
+        self.assertIsInstance(annos['x'], annotationlib.ForwardRef)
+        self.assertEqual(annos['x'].__arg__, 'undefined')
+
+        self.assertEqual(get_type_hints(C, format=annotationlib.Format.SOURCE),
+                         {'x': 'undefined'})
+
 
 class GetUtilitiesTestCase(TestCase):
     def test_get_origin(self):

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to