1010import importlib
1111import inspect
1212import os
13+ import pkgutil
1314import re
1415import sys
1516import types
@@ -164,6 +165,17 @@ def get_description(self, concise: bool = False) -> str:
164165# Core logic
165166# ====================
166167
168+ def silent_import_module (module_name : str ) -> types .ModuleType :
169+ with open (os .devnull , "w" ) as devnull :
170+ with warnings .catch_warnings (), redirect_stdout (devnull ), redirect_stderr (devnull ):
171+ warnings .simplefilter ("ignore" )
172+ runtime = importlib .import_module (module_name )
173+ # Also run the equivalent of `from module import *`
174+ # This could have the additional effect of loading not-yet-loaded submodules
175+ # mentioned in __all__
176+ __import__ (module_name , fromlist = ["*" ])
177+ return runtime
178+
167179
168180def test_module (module_name : str ) -> Iterator [Error ]:
169181 """Tests a given module's stub against introspecting it at runtime.
@@ -175,18 +187,14 @@ def test_module(module_name: str) -> Iterator[Error]:
175187 """
176188 stub = get_stub (module_name )
177189 if stub is None :
178- yield Error ([module_name ], "failed to find stubs" , MISSING , None , runtime_desc = "N/A" )
190+ runtime_desc = repr (sys .modules [module_name ]) if module_name in sys .modules else "N/A"
191+ yield Error (
192+ [module_name ], "failed to find stubs" , MISSING , None , runtime_desc = runtime_desc
193+ )
179194 return
180195
181196 try :
182- with open (os .devnull , "w" ) as devnull :
183- with warnings .catch_warnings (), redirect_stdout (devnull ), redirect_stderr (devnull ):
184- warnings .simplefilter ("ignore" )
185- runtime = importlib .import_module (module_name )
186- # Also run the equivalent of `from module import *`
187- # This could have the additional effect of loading not-yet-loaded submodules
188- # mentioned in __all__
189- __import__ (module_name , fromlist = ["*" ])
197+ runtime = silent_import_module (module_name )
190198 except Exception as e :
191199 yield Error ([module_name ], f"failed to import, { type (e ).__name__ } : { e } " , stub , MISSING )
192200 return
@@ -1289,7 +1297,18 @@ def build_stubs(modules: List[str], options: Options, find_submodules: bool = Fa
12891297 else :
12901298 found_sources = find_module_cache .find_modules_recursive (module )
12911299 sources .extend (found_sources )
1300+ # find submodules via mypy
12921301 all_modules .extend (s .module for s in found_sources if s .module not in all_modules )
1302+ # find submodules via pkgutil
1303+ try :
1304+ runtime = silent_import_module (module )
1305+ all_modules .extend (
1306+ m .name
1307+ for m in pkgutil .walk_packages (runtime .__path__ , runtime .__name__ + "." )
1308+ if m .name not in all_modules
1309+ )
1310+ except Exception :
1311+ pass
12931312
12941313 if sources :
12951314 try :
0 commit comments