99import pickle
1010from string .templatelib import Template , Interpolation
1111import random
12+ import types
1213import typing
1314import sys
1415import unittest
@@ -1696,8 +1697,9 @@ def __init__(self, format, /, __Format=Format,
16961697 self .assertEqual (annotations , {"x" : int })
16971698
16981699 def test_callable_generic_class_annotate_forwardref_value_fallback (self ):
1699- # If Format.STRING and Format.VALUE_WITH_FAKE_GLOBALS are not
1700- # supported fall back to Format.VALUE and convert to strings
1700+ # Generics that inherit from builtins become types.GenericAlias objects.
1701+ # This is special-case in annotationlib to ensure the constructor is handled
1702+ # as with standard classes and __orig_class__ is set correctly.
17011703 class Annotate [T ](dict [T ]):
17021704 def __init__ (self , format , / , __Format = Format ,
17031705 __NotImplementedError = NotImplementedError ):
@@ -1714,6 +1716,39 @@ def __init__(self, format, /, __Format=Format,
17141716 self .assertEqual (annotations , {"x" : int })
17151717 self .assertEqual (annotations .__orig_class__ , Annotate [int ])
17161718
1719+ def test_callable_typing_generic_class_annotate_forwardref_value_fallback (self ):
1720+ # Standard generics are 'typing._GenericAlias' objects. These are implemented
1721+ # in Python with a __call__ method (in _typing.BaseGenericAlias), so should work
1722+ # as with any callable class instance.
1723+ class Annotate [T ]:
1724+ def __init__ (self , format , / , __Format = Format ,
1725+ __NotImplementedError = NotImplementedError ):
1726+ if format == __Format .VALUE :
1727+ self .data = {"x" : int }
1728+ else :
1729+ raise __NotImplementedError (format )
1730+ def __getitem__ (self , item ):
1731+ return self .data [item ]
1732+ def __iter__ (self ):
1733+ return iter (self .data )
1734+ def __len__ (self ):
1735+ return len (self .data )
1736+ def __getattr__ (self , attr ):
1737+ val = getattr (collections .abc .Mapping , attr )
1738+ if isinstance (val , types .FunctionType ):
1739+ return types .MethodType (val , self )
1740+ return val
1741+ def __eq__ (self , other ):
1742+ return dict (self .items ()) == dict (other .items ())
1743+
1744+ annotations = annotationlib .call_annotate_function (
1745+ Annotate [int ],
1746+ Format .FORWARDREF ,
1747+ )
1748+
1749+ self .assertEqual (annotations , {"x" : int })
1750+ self .assertEqual (annotations .__orig_class__ , Annotate [int ])
1751+
17171752 def test_callable_partial_annotate_forwardref_value_fallback (self ):
17181753 # If Format.STRING and Format.VALUE_WITH_FAKE_GLOBALS are not
17191754 # supported fall back to Format.VALUE and convert to strings
0 commit comments