@@ -161,6 +161,10 @@ def test_module(module_name: str) -> Iterator[Error]:
161161 with warnings .catch_warnings ():
162162 warnings .simplefilter ("ignore" )
163163 runtime = importlib .import_module (module_name )
164+ # Also run the equivalent of `from module import *`
165+ # This could have the additional effect of loading not-yet-loaded submodules
166+ # mentioned in __all__
167+ __import__ (module_name , fromlist = ["*" ])
164168 except Exception as e :
165169 yield Error ([module_name ], "failed to import: {}" .format (e ), stub , MISSING )
166170 return
@@ -200,26 +204,29 @@ def verify_mypyfile(
200204 to_check = set (
201205 m
202206 for m , o in stub .names .items ()
207+ # TODO: change `o.module_public` to `not o.module_hidden`
203208 if o .module_public and (not m .startswith ("_" ) or hasattr (runtime , m ))
204209 )
205210 runtime_public_contents = [
206211 m
207212 for m in dir (runtime )
208213 if not m .startswith ("_" )
209- # Ensure that the object's module is `runtime`, e.g. so that we don't pick up reexported
210- # modules and infinitely recurse. Unfortunately, there's no way to detect an explicit
211- # reexport missing from the stubs (that isn't specified in __all__)
214+ # Ensure that the object's module is `runtime`, since in the absence of __all__ we don't
215+ # have a good way to detect re-exports at runtime.
212216 and getattr (getattr (runtime , m ), "__module__" , None ) == runtime .__name__
213217 ]
214218 # Check all things declared in module's __all__, falling back to runtime_public_contents
215219 to_check .update (getattr (runtime , "__all__" , runtime_public_contents ))
216220 to_check .difference_update ({"__file__" , "__doc__" , "__name__" , "__builtins__" , "__package__" })
217221
218222 for entry in sorted (to_check ):
219- stub_to_verify = stub .names [entry ].node if entry in stub .names else MISSING
220- assert stub_to_verify is not None
223+ stub_entry = stub .names [entry ].node if entry in stub .names else MISSING
224+ if isinstance (stub_entry , nodes .MypyFile ):
225+ # Don't recursively check exported modules, since that leads to infinite recursion
226+ continue
227+ assert stub_entry is not None
221228 yield from verify (
222- stub_to_verify ,
229+ stub_entry ,
223230 getattr (runtime , entry , MISSING ),
224231 object_path + [entry ],
225232 )
0 commit comments