diff --git a/pytype/load_pytd.py b/pytype/load_pytd.py index cba0ca2e0..756e25d35 100644 --- a/pytype/load_pytd.py +++ b/pytype/load_pytd.py @@ -624,13 +624,17 @@ def finish_and_verify_ast(self, mod_ast): if mod_ast: try: self._resolver.verify(mod_ast) - except (BadDependencyError, visitors.ContainerError): + except (BadDependencyError, visitors.ContainerError) as e: # In the case of a circular import, an external type may be left # unresolved, so we re-resolve lookups in this module and its direct # dependencies. Technically speaking, we should re-resolve all # transitive imports, but lookups are expensive. dependencies = self._resolver.collect_dependencies(mod_ast) for k in dependencies: + if k not in self._modules: + raise ( + BadDependencyError("Can't find pyi for %r" % k, mod_ast.name) + ) from e self._modules[k].ast = self._resolve_external_types( self._modules[k].ast) mod_ast = self._resolve_external_types(mod_ast) diff --git a/pytype/tests/test_pyi1.py b/pytype/tests/test_pyi1.py index c7a45e563..92434f9fc 100644 --- a/pytype/tests/test_pyi1.py +++ b/pytype/tests/test_pyi1.py @@ -898,6 +898,19 @@ class X: import bad # pyi-error """, pythonpath=[d.path]) + def test_nonexistent_import(self): + with file_utils.Tempdir() as d: + d.create_file("bad.pyi", """ + import nonexistent + x = nonexistent.x + """) + err = self.CheckWithErrors(""" + import bad # pyi-error[e] + """, pythonpath=[d.path]) + self.assertErrorSequences(err, { + "e": ["Couldn't import pyi", "nonexistent", "referenced from", "bad"] + }) + if __name__ == "__main__": test_base.main()