@@ -155,6 +155,9 @@ class TypeshedFinder:
155
155
_attribute_cache : Dict [Tuple [str , str , bool ], Value ] = field (
156
156
default_factory = dict , repr = False , init = False
157
157
)
158
+ _active_infos : List [typeshed_client .resolver .ResolvedName ] = field (
159
+ default_factory = list , repr = False , init = False
160
+ )
158
161
159
162
@classmethod
160
163
def make (cls , options : Options , * , verbose : bool = False ) -> "TypeshedFinder" :
@@ -860,7 +863,7 @@ def _parse_call_assignment(
860
863
861
864
def make_synthetic_type (self , module : str , info : typeshed_client .NameInfo ) -> Value :
862
865
fq_name = f"{ module } .{ info .name } "
863
- bases = self .get_bases_for_fq_name ( fq_name )
866
+ bases = self ._get_bases_from_info ( info , module )
864
867
typ = TypedValue (fq_name )
865
868
if bases is not None :
866
869
if any (
@@ -908,6 +911,19 @@ def _make_td_value(self, field: Value, total: bool) -> Tuple[bool, Value]:
908
911
909
912
def _value_from_info (
910
913
self , info : typeshed_client .resolver .ResolvedName , module : str
914
+ ) -> Value :
915
+ # This guard against infinite recursion if a type refers to itself
916
+ # (real-world example: os._ScandirIterator).
917
+ if info in self ._active_infos :
918
+ return AnyValue (AnySource .inference )
919
+ self ._active_infos .append (info )
920
+ try :
921
+ return self ._value_from_info_inner (info , module )
922
+ finally :
923
+ self ._active_infos .pop ()
924
+
925
+ def _value_from_info_inner (
926
+ self , info : typeshed_client .resolver .ResolvedName , module : str
911
927
) -> Value :
912
928
if isinstance (info , typeshed_client .ImportedInfo ):
913
929
return self ._value_from_info (info .info , "." .join (info .source_module ))
@@ -945,7 +961,7 @@ def _value_from_info(
945
961
return val
946
962
if info .ast .value :
947
963
return self ._parse_expr (info .ast .value , module )
948
- elif isinstance (info .ast , ast .FunctionDef ):
964
+ elif isinstance (info .ast , ( ast .FunctionDef , ast . AsyncFunctionDef ) ):
949
965
sig = self ._get_signature_from_info (info , None , fq_name , module )
950
966
if sig is not None :
951
967
return CallableValue (sig )
0 commit comments