Skip to content

Commit a942431

Browse files
committed
Test generic annotation evaluation
1 parent 3acc941 commit a942431

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

‎Lib/test/test_annotationlib.py‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,74 @@ class UnionForwardrefs:
237237
arg2, support.EqualToForwardRef("undefined", is_class=True, owner=UnionForwardrefs)
238238
)
239239

240+
def test_nested_deferred(self):
241+
# Test that ForwardReferences inside generic aliases and
242+
# typing.Annotated are correctly caught and resolved.
243+
244+
class NestedForwardRefs:
245+
genericalias: Unknown1[str, list[Unknown2]]
246+
annotated: Unknown1[str, typing.Annotated[Unknown2, '']]
247+
248+
annos = get_annotations(NestedForwardRefs, format=Format.FORWARDREF)
249+
250+
gen = annos['genericalias']
251+
annotated = annos['annotated']
252+
253+
Unknown1 = tuple
254+
# Unknown2 is still undefined, these should raise
255+
with self.assertRaises(NameError):
256+
gen.evaluate()
257+
with self.assertRaises(NameError):
258+
annotated.evaluate()
259+
260+
# Test that the annotations fully evaluate now both unknowns are defined
261+
Unknown2 = str
262+
self.assertEqual(
263+
gen.evaluate(),
264+
tuple[str, list[str]],
265+
)
266+
267+
self.assertEqual(
268+
annotated.evaluate(),
269+
tuple[str, typing.Annotated[str, '']],
270+
)
271+
272+
def test_nested_special_generic(self):
273+
# Test that ForwardRef works correctly for generic aliases that aren't
274+
# created through subscripting
275+
class NonSubscriptableGeneric:
276+
@classmethod
277+
def get_generic(cls, *args):
278+
return types.GenericAlias(cls, args)
279+
280+
nsrepr = type_repr(NonSubscriptableGeneric)
281+
282+
with self.assertRaises(TypeError):
283+
_ = NonSubscriptableGeneric[str]
284+
285+
class C:
286+
x: Unknown1[NonSubscriptableGeneric.get_generic(str, Unknown2)]
287+
288+
ann = get_annotations(C, format=Format.FORWARDREF)['x']
289+
290+
Unknown1 = list
291+
292+
with self.assertRaises(NameError):
293+
ann.evaluate()
294+
295+
Unknown2 = int
296+
297+
self.assertEqual(
298+
ann.evaluate(),
299+
list[NonSubscriptableGeneric.get_generic(str, int)],
300+
)
301+
302+
# The string representation should look like the __repr__ for GenericAlias
303+
self.assertEqual(
304+
ann.evaluate(format=Format.STRING),
305+
f"Unknown1[{nsrepr}[str, Unknown2]]",
306+
)
307+
240308

241309
class TestStringFormat(unittest.TestCase):
242310
def test_closure(self):

0 commit comments

Comments
 (0)