@@ -62,7 +62,6 @@ public class TypeShed {
6262 private static Map <String , Symbol > builtins ;
6363 private static final Map <String , Map <String , Symbol >> typeShedSymbols = new HashMap <>();
6464 private static final Map <String , Set <Symbol >> builtinGlobalSymbols = new HashMap <>();
65- private static final Set <String > modulesInProgress = new HashSet <>();
6665
6766 private static final String PROTOBUF_CUSTOM_STUBS = "custom_protobuf/" ;
6867 private static final String PROTOBUF = "stdlib_protobuf/" ;
@@ -76,6 +75,7 @@ public class TypeShed {
7675
7776 // This is needed for some Python 2 modules whose name differ from their Python 3 counterpart by capitalization only.
7877 private static final Map <String , String > MODULES_TO_DISAMBIGUATE = new HashMap <>();
78+
7979 static {
8080 MODULES_TO_DISAMBIGUATE .put ("ConfigParser" , "2@ConfigParser" );
8181 MODULES_TO_DISAMBIGUATE .put ("Queue" , "2@Queue" );
@@ -138,11 +138,15 @@ private static boolean searchedModuleMatchesCurrentProject(String searchedModule
138138 * Returns map of exported symbols by name for a given module
139139 */
140140 public static Map <String , Symbol > symbolsForModule (String moduleName ) {
141+ return symbolsForModule (moduleName , new HashSet <>());
142+ }
143+
144+ private static Map <String , Symbol > symbolsForModule (String moduleName , Set <String > modulesInProgress ) {
141145 if (searchedModuleMatchesCurrentProject (moduleName )) {
142146 return Collections .emptyMap ();
143147 }
144148 if (!TypeShed .typeShedSymbols .containsKey (moduleName )) {
145- Map <String , Symbol > symbols = searchTypeShedForModule (moduleName );
149+ Map <String , Symbol > symbols = searchTypeShedForModule (moduleName , modulesInProgress );
146150 typeShedSymbols .put (moduleName , symbols );
147151 return symbols ;
148152 }
@@ -231,7 +235,7 @@ public static boolean isValidForProjectPythonVersion(List<String> validForPython
231235 if (validForPythonVersions .isEmpty ()) {
232236 return true ;
233237 }
234- if (supportedPythonVersions == null ) {
238+ if (supportedPythonVersions == null ) {
235239 throw new IllegalStateException ("supportedPythonVersion is uninitialized. Call builtinSymbols() first" );
236240 }
237241 HashSet <String > intersection = new HashSet <>(validForPythonVersions );
@@ -240,6 +244,11 @@ public static boolean isValidForProjectPythonVersion(List<String> validForPython
240244 }
241245
242246 public static Set <Symbol > symbolsFromProtobufDescriptors (Set <Object > protobufDescriptors , @ Nullable String containerClassFqn , String moduleName , boolean isFromClass ) {
247+ return symbolsFromProtobufDescriptors (protobufDescriptors , containerClassFqn , moduleName , isFromClass , new HashSet <>());
248+ }
249+
250+ private static Set <Symbol > symbolsFromProtobufDescriptors (Set <Object > protobufDescriptors , @ Nullable String containerClassFqn , String moduleName , boolean isFromClass ,
251+ Set <String > modulesInProgress ) {
243252 Set <Symbol > symbols = new HashSet <>();
244253 for (Object descriptor : protobufDescriptors ) {
245254 if (descriptor instanceof SymbolsProtos .ClassSymbol classSymbolProto ) {
@@ -252,12 +261,12 @@ public static Set<Symbol> symbolsFromProtobufDescriptors(Set<Object> protobufDes
252261 if (overloadedFunctionSymbol .getDefinitionsList ().size () < 2 ) {
253262 throw new IllegalStateException ("Overloaded function symbols should have at least two definitions." );
254263 }
255- symbols .add (fromOverloadedFunction ((( OverloadedFunctionSymbol ) descriptor ) , containerClassFqn , moduleName ));
264+ symbols .add (fromOverloadedFunction (overloadedFunctionSymbol , containerClassFqn , moduleName ));
256265 }
257266 if (descriptor instanceof SymbolsProtos .VarSymbol varSymbol ) {
258267 SymbolImpl symbol = new SymbolImpl (varSymbol , moduleName , isFromClass );
259268 if (varSymbol .getIsImportedModule ()) {
260- Map <String , Symbol > moduleExportedSymbols = symbolsForModule (varSymbol .getFullyQualifiedName ());
269+ Map <String , Symbol > moduleExportedSymbols = symbolsForModule (varSymbol .getFullyQualifiedName (), modulesInProgress );
261270 moduleExportedSymbols .values ().forEach (symbol ::addChildSymbol );
262271 }
263272 symbols .add (symbol );
@@ -295,31 +304,30 @@ public static void resetBuiltinSymbols() {
295304 builtinSymbols ();
296305 }
297306
298- private static Map <String , Symbol > searchTypeShedForModule (String moduleName ) {
307+ private static Map <String , Symbol > searchTypeShedForModule (String moduleName , Set < String > modulesInProgress ) {
299308 if (modulesInProgress .contains (moduleName )) {
300309 return new HashMap <>();
301310 }
302311 modulesInProgress .add (moduleName );
303- Map <String , Symbol > customSymbols = getSymbolsFromProtobufModule (moduleName , PROTOBUF_CUSTOM_STUBS );
304- if (!customSymbols .isEmpty ()) {
305- modulesInProgress .remove (moduleName );
306- return customSymbols ;
307- }
308- Map <String , Symbol > symbolsFromProtobuf = getSymbolsFromProtobufModule (moduleName , PROTOBUF );
309- if (!symbolsFromProtobuf .isEmpty ()) {
310- modulesInProgress .remove (moduleName );
311- return symbolsFromProtobuf ;
312- }
312+ try {
313+ Map <String , Symbol > customSymbols = getSymbolsFromProtobufModule (moduleName , PROTOBUF_CUSTOM_STUBS , modulesInProgress );
314+ if (!customSymbols .isEmpty ()) {
315+ return customSymbols ;
316+ }
317+ Map <String , Symbol > symbolsFromProtobuf = getSymbolsFromProtobufModule (moduleName , PROTOBUF , modulesInProgress );
318+ if (!symbolsFromProtobuf .isEmpty ()) {
319+ return symbolsFromProtobuf ;
320+ }
313321
314- Map <String , Symbol > thirdPartySymbolsMypy = getSymbolsFromProtobufModule (moduleName , PROTOBUF_THIRD_PARTY_MYPY );
315- if (!thirdPartySymbolsMypy .isEmpty ()) {
322+ Map <String , Symbol > thirdPartySymbolsMypy = getSymbolsFromProtobufModule (moduleName , PROTOBUF_THIRD_PARTY_MYPY , modulesInProgress );
323+ if (!thirdPartySymbolsMypy .isEmpty ()) {
324+ return thirdPartySymbolsMypy ;
325+ }
326+
327+ return getSymbolsFromProtobufModule (moduleName , PROTOBUF_THIRD_PARTY , modulesInProgress );
328+ } finally {
316329 modulesInProgress .remove (moduleName );
317- return thirdPartySymbolsMypy ;
318330 }
319-
320- Map <String , Symbol > thirdPartySymbols = getSymbolsFromProtobufModule (moduleName , PROTOBUF_THIRD_PARTY );
321- modulesInProgress .remove (moduleName );
322- return thirdPartySymbols ;
323331 }
324332
325333 /**
@@ -349,12 +357,16 @@ private static boolean isAmbiguousSymbolOfClasses(Symbol symbol) {
349357 }
350358
351359 private static Map <String , Symbol > getSymbolsFromProtobufModule (String moduleName , String dirName ) {
360+ return getSymbolsFromProtobufModule (moduleName , dirName , new HashSet <>());
361+ }
362+
363+ private static Map <String , Symbol > getSymbolsFromProtobufModule (String moduleName , String dirName , Set <String > modulesInProgress ) {
352364 String fileName = MODULES_TO_DISAMBIGUATE .getOrDefault (moduleName , moduleName );
353365 InputStream resource = TypeShed .class .getResourceAsStream (dirName + fileName + ".protobuf" );
354366 if (resource == null ) {
355367 return Collections .emptyMap ();
356368 }
357- return getSymbolsFromProtobufModule (deserializedModule (moduleName , resource ));
369+ return getSymbolsFromProtobufModule (deserializedModule (moduleName , resource ), modulesInProgress );
358370 }
359371
360372 @ CheckForNull
@@ -368,6 +380,10 @@ static ModuleSymbol deserializedModule(String moduleName, InputStream resource)
368380 }
369381
370382 static Map <String , Symbol > getSymbolsFromProtobufModule (@ Nullable ModuleSymbol moduleSymbol ) {
383+ return getSymbolsFromProtobufModule (moduleSymbol , new HashSet <>());
384+ }
385+
386+ private static Map <String , Symbol > getSymbolsFromProtobufModule (@ Nullable ModuleSymbol moduleSymbol , Set <String > modulesInProgress ) {
371387 if (moduleSymbol == null ) {
372388 return Collections .emptyMap ();
373389 }
@@ -391,7 +407,7 @@ static Map<String, Symbol> getSymbolsFromProtobufModule(@Nullable ModuleSymbol m
391407
392408 for (Map .Entry <String , Set <Object >> entry : descriptorsByName .entrySet ()) {
393409 String name = entry .getKey ();
394- Set <Symbol > symbols = symbolsFromProtobufDescriptors (entry .getValue (), null , moduleSymbol .getFullyQualifiedName (), false );
410+ Set <Symbol > symbols = symbolsFromProtobufDescriptors (entry .getValue (), null , moduleSymbol .getFullyQualifiedName (), false , modulesInProgress );
395411 Symbol disambiguatedSymbol = disambiguateSymbolsWithSameName (name , symbols , moduleSymbol .getFullyQualifiedName ());
396412 deserializedSymbols .put (name , disambiguatedSymbol );
397413 }
0 commit comments