@@ -196,6 +196,7 @@ def get_annotations(
196196 obj : object ,
197197 args : dict [str , object ],
198198 key : str = '__annotate__' ,
199+ cls : type | None = None ,
199200 annos_ok : bool = True ,
200201) -> Any | None :
201202 """Get the annotations on an object, substituting in type vars."""
@@ -221,14 +222,23 @@ def get_annotations(
221222 globs .update (vars (mod ))
222223
223224 if isinstance (rr , dict ) and any (isinstance (v , str ) for v in rr .values ()):
225+ args = args .copy ()
224226 # Copy in any __type_params__ that aren't provided for, so that if
225227 # we have to eval, we have them.
226228 if params := getattr (obj , "__type_params__" , None ):
227- args = args .copy ()
228229 for param in params :
229230 if str (param ) not in args :
230231 args [str (param )] = param
231232
233+ # Include the class itself in args so that self-referential string
234+ # annotations (e.g. from `from __future__ import annotations`) in
235+ # nested scopes can be resolved during eval. (This only half
236+ # solves that general problem, but it is the best we can do.)
237+ rcls = cls or obj
238+ if isinstance (rcls , (type , typing .TypeAliasType )):
239+ if rcls .__name__ not in args :
240+ args [rcls .__name__ ] = rcls
241+
232242 for k , v in rr .items ():
233243 # Eval strings
234244 if isinstance (v , str ):
@@ -248,15 +258,7 @@ def get_local_defns(boxed: Boxed) -> tuple[dict[str, Any], dict[str, Any]]:
248258 annos : dict [str , Any ] = {}
249259 dct : dict [str , Any ] = {}
250260
251- # Include the class itself in args so that self-referential string
252- # annotations (e.g. from `from __future__ import annotations`) in
253- # nested scopes can be resolved during eval. (This only half
254- # solves that general problem, but it is the best we can do.)
255- str_args = boxed .str_args
256- if boxed .cls .__name__ not in str_args :
257- str_args = {** str_args , boxed .cls .__name__ : boxed .cls }
258-
259- if (rr := get_annotations (boxed .cls , str_args )) is not None :
261+ if (rr := get_annotations (boxed .cls , boxed .str_args )) is not None :
260262 annos .update (rr )
261263
262264 for name , orig in boxed .cls .__dict__ .items ():
@@ -272,7 +274,7 @@ def get_local_defns(boxed: Boxed) -> tuple[dict[str, Any], dict[str, Any]]:
272274 # __annotations__ on methods broke stuff and I didn't want
273275 # to chase it down yet.
274276 if (
275- rr := get_annotations (stuff , str_args , annos_ok = False )
277+ rr := get_annotations (stuff , boxed . str_args , cls = boxed . cls , annos_ok = False )
276278 ) is not None :
277279 local_fn = make_func (orig , rr )
278280 elif getattr (stuff , "__annotations__" , None ):
0 commit comments