@@ -8758,53 +8758,6 @@ def unroll_cases(cases):
87588758 Format .STRING : "Y.bT" ,
87598759 },
87608760 ],
8761- "T_in_Y" : [
8762- {
8763- "owner" : None ,
8764- "type_params" : Y_type_params ,
8765- Format .VALUE : Y_type_params [0 ],
8766- Format .FORWARDREF : Y_type_params [0 ],
8767- Format .STRING : "T_in_Y" ,
8768- },
8769- {
8770- "owner" : None ,
8771- "type_params" : None ,
8772- Format .VALUE : NameError ,
8773- Format .FORWARDREF : typing .ForwardRef ("T_in_Y" ),
8774- Format .STRING : "T_in_Y" ,
8775- },
8776- {
8777- # Owner with such an attribute name
8778- "owner" : X ,
8779- "type_params" : None ,
8780- Format .VALUE : NameError ,
8781- Format .FORWARDREF : typing .ForwardRef ("T_in_Y" ),
8782- Format .STRING : "T_in_Y" ,
8783- },
8784- {
8785- # Owner without __type_params__
8786- "owner" : Y ,
8787- "type_params" : None ,
8788- Format .VALUE : NameError ,
8789- Format .FORWARDREF : typing .ForwardRef ("T_in_Y" ),
8790- Format .STRING : "T_in_Y" ,
8791- },
8792- {
8793- "owner" : Y ,
8794- "type_params" : Y_type_params ,
8795- Format .VALUE : Y_type_params [0 ],
8796- Format .FORWARDREF : Y_type_params [0 ],
8797- Format .STRING : "T_in_Y" ,
8798- },
8799- {
8800- # Owner with __type_params__
8801- "owner" : Z ,
8802- "type_params" : None ,
8803- Format .VALUE : Y_type_params [0 ],
8804- Format .FORWARDREF : Y_type_params [0 ],
8805- Format .STRING : "T_in_Y" ,
8806- },
8807- ],
88088761 # Special cases for typing._type_check.
88098762 # Note: Depending on `is_class` and `is_argument` will raise TypeError
88108763 # therefore `expected` is converted in the generator.
@@ -8927,6 +8880,12 @@ def unroll_cases(cases):
89278880 )
89288881 self .assertEqual (result , expected )
89298882
8883+ def test_forward_ref_fallback (self ):
8884+ with self .assertRaises (NameError ):
8885+ evaluate_forward_ref (typing .ForwardRef ("unbound" ), format = Format .VALUE )
8886+ ref = typing .ForwardRef ("unbound" )
8887+ self .assertIs (evaluate_forward_ref (ref , format = Format .FORWARDREF ), ref )
8888+
89308889 def test_evaluate_with_type_params (self ):
89318890 # Use a T name that is not in globals
89328891 self .assertNotIn ("Tx" , globals ())
@@ -8946,6 +8905,8 @@ class Gen[Tx]:
89468905 """ ), None , ns )
89478906 Gen = ns ["Gen" ]
89488907
8908+ # owner=None, type_params=None
8909+ # NOTE: The behavior of owner=None might change in the future when ForwardRef.__owner__ is available
89498910 with self .assertRaises (NameError ):
89508911 evaluate_forward_ref (typing .ForwardRef ("Tx" ))
89518912 with self .assertRaises (NameError ):
@@ -8955,10 +8916,21 @@ class Gen[Tx]:
89558916
89568917 (Tx ,) = Gen .__type_params__
89578918 self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Tx" ), type_params = Gen .__type_params__ ), Tx )
8919+
89588920 # For this test its important that Tx is not a global variable, i.e. do not use "T" here
89598921 self .assertNotIn ("Tx" , globals ())
89608922 self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Tx" ), owner = Gen ), Tx )
89618923
8924+ # Different type_params take precedence
8925+ not_Tx = TypeVar ("Tx" ) # different TypeVar with same name
8926+ self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Tx" ), type_params = (not_Tx ,), owner = Gen ), not_Tx )
8927+
8928+ # globals can take higher precedence
8929+ if _FORWARD_REF_HAS_CLASS :
8930+ self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Tx" , is_class = True ), owner = Gen , globals = {"Tx" : str }), str )
8931+ self .assertIs (evaluate_forward_ref (typing .ForwardRef ("Tx" , is_class = True ), owner = Gen , type_params = (not_Tx ,), globals = {"Tx" : str }), str )
8932+
8933+
89628934 with self .assertRaises (NameError ):
89638935 evaluate_forward_ref (typing .ForwardRef ("alias" ), type_params = Gen .__type_params__ )
89648936 self .assertIs (evaluate_forward_ref (typing .ForwardRef ("alias" ), owner = Gen ), int )
0 commit comments