@@ -1533,6 +1533,28 @@ def __init__(self, format, /, __Format=Format, __NotImplementedError=NotImplemen
15331533
15341534 self .assertEqual (annotations , {"x" : int })
15351535
1536+ def test_callable_generic_class_annotate_forwardref_fakeglobals (self ):
1537+ # If Format.FORWARDREF is not supported, use Format.VALUE_WITH_FAKE_GLOBALS
1538+ # before falling back to Format.VALUE
1539+ class Annotate [K , V ](dict [K , V ]):
1540+ def __init__ (self , format , / , __Format = Format , __NotImplementedError = NotImplementedError ):
1541+ if format == __Format .VALUE :
1542+ super ().__init__ ({'x' : str })
1543+ elif format == __Format .VALUE_WITH_FAKE_GLOBALS :
1544+ super ().__init__ ({'x' : int })
1545+ else :
1546+ raise __NotImplementedError (format )
1547+
1548+ annotations = annotationlib .call_annotate_function (
1549+ Annotate [str , type ],
1550+ Format .FORWARDREF
1551+ )
1552+
1553+ self .assertEqual (annotations , {"x" : int })
1554+
1555+ # We will have to manually set the __orig_class__, ensure it is correct.
1556+ self .assertEqual (annotations .__orig_class__ , Annotate [str , type ])
1557+
15361558 def test_user_annotate_forwardref_value_fallback (self ):
15371559 # If Format.FORWARDREF and Format.VALUE_WITH_FAKE_GLOBALS are not supported
15381560 # use Format.VALUE
@@ -1586,6 +1608,48 @@ def annotate(format, /, __Format=Format, __NotImplementedError=NotImplementedErr
15861608
15871609 self .assertEqual (annotations , {"x" : "int" })
15881610
1611+ def test_callable_generic_class_annotate_string_fakeglobals (self ):
1612+ # If Format.STRING is not supported but Format.VALUE_WITH_FAKE_GLOBALS is
1613+ # prefer that over Format.VALUE
1614+ class Annotate [T ]:
1615+ __slots__ = "data" ,
1616+
1617+ def __init__ (self , format , / , __Format = Format ,
1618+ __NotImplementedError = NotImplementedError ):
1619+ if format == __Format .VALUE :
1620+ self .data = {"x" : str }
1621+ elif format == __Format .VALUE_WITH_FAKE_GLOBALS :
1622+ self .data = {"x" : int }
1623+ else :
1624+ raise __NotImplementedError (format )
1625+ def __getitem__ (self , item ):
1626+ return self .data [item ]
1627+ def __iter__ (self ):
1628+ return iter (self .data )
1629+ def __len__ (self ):
1630+ return len (self .data )
1631+ def __getattr__ (self , attr ):
1632+ val = getattr (collections .abc .Mapping , attr )
1633+ if isinstance (val , types .FunctionType ):
1634+ return types .MethodType (val , self )
1635+ return val
1636+ def __eq__ (self , other ):
1637+ return dict (self .items ()) == dict (other .items ())
1638+
1639+ # Subscripting a user-created class will return a typing._GenericAlias.
1640+ # We want to check that types.GenericAlias objects are created properly,
1641+ # so manually create it with the documented constructor.
1642+ annotations = annotationlib .call_annotate_function (
1643+ types .GenericAlias (Annotate , (int ,)),
1644+ Format .STRING ,
1645+ )
1646+
1647+ self .assertEqual (annotations , {"x" : "int" })
1648+
1649+ # A __slots__ class can't have __orig_class__ set unless already specified.
1650+ # Ensure that the error passes silently.
1651+ self .assertNotHasAttr (annotations , "__orig_class__" )
1652+
15891653 def test_user_annotate_string_value_fallback (self ):
15901654 # If Format.STRING and Format.VALUE_WITH_FAKE_GLOBALS are not
15911655 # supported fall back to Format.VALUE and convert to strings
0 commit comments