@@ -94,6 +94,10 @@ def f(
9494 alpha : some | obj ,
9595 beta : + some ,
9696 gamma : some < obj ,
97+ delta : some | {obj : module },
98+ epsilon : some | {obj , module },
99+ zeta : some | [obj ],
100+ eta : some | (),
97101 ):
98102 pass
99103
@@ -122,6 +126,69 @@ def f(
122126 self .assertIsInstance (gamma_anno , ForwardRef )
123127 self .assertEqual (gamma_anno , support .EqualToForwardRef ("some < obj" , owner = f ))
124128
129+ delta_anno = anno ["delta" ]
130+ self .assertIsInstance (delta_anno , ForwardRef )
131+ self .assertEqual (delta_anno , support .EqualToForwardRef ("some | {obj: module}" , owner = f ))
132+
133+ epsilon_anno = anno ["epsilon" ]
134+ self .assertIsInstance (epsilon_anno , ForwardRef )
135+ self .assertEqual (epsilon_anno , support .EqualToForwardRef ("some | {obj, module}" , owner = f ))
136+
137+ zeta_anno = anno ["zeta" ]
138+ self .assertIsInstance (zeta_anno , ForwardRef )
139+ self .assertEqual (zeta_anno , support .EqualToForwardRef ("some | [obj]" , owner = f ))
140+
141+ eta_anno = anno ["eta" ]
142+ self .assertIsInstance (eta_anno , ForwardRef )
143+ self .assertEqual (eta_anno , support .EqualToForwardRef ("some | ()" , owner = f ))
144+
145+ def test_partially_nonexistent (self ):
146+ # These annotations start with a non-existent variable and then use
147+ # global types with defined values. This partially evaluates by putting
148+ # those globals into `fwdref.__extra_names__`.
149+ def f (
150+ x : obj | int ,
151+ y : container [int :obj , int ],
152+ z : dict_val | {str : int },
153+ alpha : set_val | {str , int },
154+ beta : obj | bool | int ,
155+ gamma : obj | call_func (int , kwd = bool ),
156+ ):
157+ pass
158+
159+ def func (* args , ** kwargs ):
160+ return Union [* args , * (kwargs .values ())]
161+
162+ anno = get_annotations (f , format = Format .FORWARDREF )
163+ globals_ = {
164+ "obj" : str , "container" : list , "dict_val" : {1 : 2 }, "set_val" : {1 , 2 },
165+ "call_func" : func
166+ }
167+
168+ x_anno = anno ["x" ]
169+ self .assertIsInstance (x_anno , ForwardRef )
170+ self .assertEqual (x_anno .evaluate (globals = globals_ ), str | int )
171+
172+ y_anno = anno ["y" ]
173+ self .assertIsInstance (y_anno , ForwardRef )
174+ self .assertEqual (y_anno .evaluate (globals = globals_ ), list [int :str , int ])
175+
176+ z_anno = anno ["z" ]
177+ self .assertIsInstance (z_anno , ForwardRef )
178+ self .assertEqual (z_anno .evaluate (globals = globals_ ), {1 : 2 } | {str : int })
179+
180+ alpha_anno = anno ["alpha" ]
181+ self .assertIsInstance (alpha_anno , ForwardRef )
182+ self .assertEqual (alpha_anno .evaluate (globals = globals_ ), {1 , 2 } | {str , int })
183+
184+ beta_anno = anno ["beta" ]
185+ self .assertIsInstance (beta_anno , ForwardRef )
186+ self .assertEqual (beta_anno .evaluate (globals = globals_ ), str | bool | int )
187+
188+ gamma_anno = anno ["gamma" ]
189+ self .assertIsInstance (gamma_anno , ForwardRef )
190+ self .assertEqual (gamma_anno .evaluate (globals = globals_ ), str | func (int , kwd = bool ))
191+
125192 def test_partially_nonexistent_union (self ):
126193 # Test unions with '|' syntax equal unions with typing.Union[] with some forwardrefs
127194 class UnionForwardrefs :
0 commit comments