# HG changeset patch # Parent ea576db138278c9f80fe2be213e9d19669a802eb Issue #14285: Do not catch exceptions initializing any ancestor package The previous fix only handled the case of the parent package of __main__ failing to initialize. diff -r ea576db13827 Lib/runpy.py --- a/Lib/runpy.py Thu Dec 03 22:27:31 2015 +0200 +++ b/Lib/runpy.py Fri Dec 04 02:12:39 2015 +0000 @@ -100,6 +100,22 @@ # Helper to get the loader, code and filename for a module def _get_module_details(mod_name, error=ImportError): + # Import each ancestor package to avoid catching initialization errors + dot = 0 + while True: + dot = mod_name.find(".", dot) + if dot < 0: + break + package = mod_name[:dot] + try: + if importlib.util.find_spec(package) is None: + raise ImportError("No module named {!r}".format(package)) + except (ImportError, AttributeError, TypeError, ValueError) as ex: + msg = "Error while finding spec for {!r} ({}: {})" + raise error(msg.format(mod_name, type(ex), ex)) from ex + __import__(package) + dot += 1 + try: spec = importlib.util.find_spec(mod_name) except (ImportError, AttributeError, TypeError, ValueError) as ex: @@ -113,11 +129,10 @@ if spec.submodule_search_locations is not None: if mod_name == "__main__" or mod_name.endswith(".__main__"): raise error("Cannot use package as __main__ module") - __import__(mod_name) # Do not catch exceptions initializing package try: pkg_main_name = mod_name + ".__main__" - return _get_module_details(pkg_main_name) - except ImportError as e: + return _get_module_details(pkg_main_name, error) + except error as e: raise error(("%s; %r is a package and cannot " + "be directly executed") %(e, mod_name)) loader = spec.loader diff -r ea576db13827 Lib/test/test_cmd_line_script.py --- a/Lib/test/test_cmd_line_script.py Thu Dec 03 22:27:31 2015 +0200 +++ b/Lib/test/test_cmd_line_script.py Fri Dec 04 02:12:39 2015 +0000 @@ -427,8 +427,7 @@ tests = ( ('builtins', br'No code object available'), ('builtins.x', br'Error while finding spec.*AttributeError'), - ('builtins.x.y', br'Error while finding spec.*' - br'ImportError.*No module named.*not a package'), + ('builtins.x.y', br'Error while finding spec.*AttributeError'), ('os.path', br'loader.*cannot handle'), ('importlib', br'No module named.*' br'is a package and cannot be directly executed'), diff -r ea576db13827 Lib/test/test_runpy.py --- a/Lib/test/test_runpy.py Thu Dec 03 22:27:31 2015 +0200 +++ b/Lib/test/test_runpy.py Fri Dec 04 02:12:39 2015 +0000 @@ -460,6 +460,12 @@ self.assertNotIn("finding spec", format(err)) else: self.fail("Nothing raised; expected {}".format(name)) + try: + run_module(mod_name + ".submodule") + except exception as err: + self.assertNotIn("finding spec", format(err)) + else: + self.fail("Nothing raised; expected {}".format(name)) def test_run_package_in_namespace_package(self): for depth in range(1, 4):