@@ -35,6 +35,12 @@ def __post_init__(self):
3535 _compute_mro (self ),
3636 )
3737
38+ def alias_type (self ):
39+ if self .args :
40+ return self .cls [* self .args .values ()]
41+ else :
42+ return self .cls
43+
3844 def __repr__ (self ):
3945 return f"Boxed<{ self .cls } { self .args } >"
4046
@@ -253,39 +259,58 @@ def apply(
253259 cls_boxed = box (cls )
254260 mro_boxed = cls_boxed .mro
255261
256- annos : dict [str , Any ] = {}
257- dct : dict [str , Any ] = {}
258-
259- # We create it early so we can add it to seen, to handle recursion
260- ctx .seen [cls ] = ret = type (
261- cls .__name__ ,
262- (_eval_typing ._EvalProxy ,),
263- {
264- "__module__" : cls .__module__ ,
265- "__name__" : cls .__name__ ,
266- "__origin__" : cls ,
267- },
268- )
269-
270262 # TODO: I think we want to create the whole mro chain...
271263 # before we evaluate the contents?
272264
273- # Run through the mro
265+ # FIXME: right now we flatten out all the attributes... but should we??
266+
267+ new = {}
268+
269+ # Run through the mro and populate everything
274270 for boxed in reversed (mro_boxed ):
275- lannos , ldct = _get_local_defns (boxed )
276- annos .update (lannos )
277- dct .update (ldct )
271+ # We create it early so we can add it to seen, to handle recursion
272+ # XXX: currently we are doing this even for types with no generics...
273+ # that simplifies the flow... - probably keep it this way until
274+ # we stop flattening attributes into every class
275+ name = boxed .cls .__name__
276+ cboxed : Any
277+ cboxed = type (
278+ boxed .cls .__name__ ,
279+ (_eval_typing ._EvalProxy ,),
280+ {
281+ "__module__" : boxed .cls .__module__ ,
282+ "__name__" : name ,
283+ "__origin__" : boxed .cls ,
284+ "__local_args__" : tuple (boxed .args .values ()),
285+ },
286+ )
287+ ctx .seen [boxed .alias_type ()] = new [boxed ] = cboxed
288+
289+ annos : dict [str , Any ] = {}
290+ dct : dict [str , Any ] = {}
291+
292+ cboxed .__local_annotations__ , cboxed .__local_defns__ = _get_local_defns (
293+ boxed
294+ )
295+ for base in reversed (boxed .mro ):
296+ cbase = new [base ]
297+ annos .update (cbase .__local_annotations__ )
298+ dct .update (cbase .__local_defns__ ) # uh.
278299
279- for k , v in annos .items ():
280- annos [k ] = _eval_typing ._eval_types (v , ctx = ctx )
300+ cboxed .__defn_names__ = set (dct )
301+ cboxed .__annotations__ = annos
302+ cboxed .__generalized_mro__ = [new [b ] for b in boxed .mro ]
281303
282- for k , v in dct .items ():
283- dct [ k ] = _eval_typing . _eval_types ( v , ctx = ctx )
304+ for k , v in dct .items ():
305+ setattr ( cboxed , k , v )
284306
285- dct ["__annotations__" ] = annos
286- dct ["__generalized_mro__" ] = mro_boxed
307+ # Run through the mro again and evaluate everything
308+ for cboxed in new .values ():
309+ for k , v in cboxed .__annotations__ .items ():
310+ cboxed .__annotations__ [k ] = _eval_typing ._eval_types (v , ctx = ctx )
287311
288- for k , v in dct .items ():
289- setattr (ret , k , v )
312+ for k in cboxed .__defn_names__ :
313+ v = cboxed .__dict__ [k ]
314+ setattr (cboxed , k , _eval_typing ._eval_types (v , ctx = ctx ))
290315
291- return ret
316+ return new [ cls_boxed ]
0 commit comments