Skip to content

Commit

Permalink
pythongh-124206: Fix calling get_annotate_function() on static types
Browse files Browse the repository at this point in the history
Fixes python#124206. No news entry because the bug this fixes was never
released.
  • Loading branch information
JelleZijlstra committed Sep 18, 2024
1 parent 3b6bfa7 commit eb1cc01
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Lib/annotationlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
21 changes: 21 additions & 0 deletions Lib/test/test_annotationlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
19 changes: 19 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down

0 comments on commit eb1cc01

Please sign in to comment.