@@ -244,14 +244,16 @@ def inner(*args, **kwds):
244244 return inner
245245
246246
247- def _eval_type (t , globalns , localns ):
247+ def _eval_type (t , globalns , localns , recursive_guard = frozenset () ):
248248 """Evaluate all forward reverences in the given type t.
249249 For use of globalns and localns see the docstring for get_type_hints().
250+ recursive_guard is used to prevent prevent infinite recursion
251+ with recursive ForwardRef.
250252 """
251253 if isinstance (t , ForwardRef ):
252- return t ._evaluate (globalns , localns )
254+ return t ._evaluate (globalns , localns , recursive_guard )
253255 if isinstance (t , (_GenericAlias , GenericAlias )):
254- ev_args = tuple (_eval_type (a , globalns , localns ) for a in t .__args__ )
256+ ev_args = tuple (_eval_type (a , globalns , localns , recursive_guard ) for a in t .__args__ )
255257 if ev_args == t .__args__ :
256258 return t
257259 if isinstance (t , GenericAlias ):
@@ -477,18 +479,24 @@ def __init__(self, arg, is_argument=True):
477479 self .__forward_value__ = None
478480 self .__forward_is_argument__ = is_argument
479481
480- def _evaluate (self , globalns , localns ):
482+ def _evaluate (self , globalns , localns , recursive_guard ):
483+ if self .__forward_arg__ in recursive_guard :
484+ return self
481485 if not self .__forward_evaluated__ or localns is not globalns :
482486 if globalns is None and localns is None :
483487 globalns = localns = {}
484488 elif globalns is None :
485489 globalns = localns
486490 elif localns is None :
487491 localns = globalns
488- self . __forward_value__ = _type_check (
492+ type_ = _type_check (
489493 eval (self .__forward_code__ , globalns , localns ),
490494 "Forward references must evaluate to types." ,
491- is_argument = self .__forward_is_argument__ )
495+ is_argument = self .__forward_is_argument__ ,
496+ )
497+ self .__forward_value__ = _eval_type (
498+ type_ , globalns , localns , recursive_guard | {self .__forward_arg__ }
499+ )
492500 self .__forward_evaluated__ = True
493501 return self .__forward_value__
494502
0 commit comments