8000 bpo-30436: Fix exception raised for invalid parent. by zvyn · Pull Request #1899 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-30436: Fix exception raised for invalid parent. 8000 #1899

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 14, 2017
Merged
5 changes: 5 additions & 0 deletions Doc/library/importlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,11 @@ an :term:`importer`.

.. versionadded:: 3.4

.. versionchanged:: 3.7
Raises :exc:`ModuleNotFoundError` instead of :exc:`AttributeError` if
**package** is in fact not a package (i.e. lacks a :attr:`__path__`
attribute).

.. function:: module_from_spec(spec)

Create a new module based on **spec** and
Expand Down
11 changes: 8 additions & 3 deletions Lib/importlib/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,16 @@ def find_spec(name, package=None):
if fullname not in sys.modules:
parent_name = fullname.rpartition('.')[0]
if parent_name:
# Use builtins.__import__() in case someone replaced it.
parent = __import__(parent_name, fromlist=['__path__'])
return _find_spec(fullname, parent.__path__)
try:
parent_path = parent.__path__
except AttributeError as e:
raise ModuleNotFoundError(
f"__path__ attribute not found on {parent_name!r}"
f"while trying to find {fullname!r}", name=fullname) from e
else:
return _find_spec(fullname, None)
parent_path = None
return _find_spec(fullname, parent_path)
else:
module = sys.modules[fullname]
if module is None:
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_cmd_line_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ def test_dash_m_errors(self):
tests = (
('builtins', br'No code object available'),
('builtins.x', br'Error while finding module specification.*'
br'AttributeError'),
br'ModuleNotFoundError'),
('builtins.x.y', br'Error while finding module specification.*'
br'ModuleNotFoundError.*No module named.*not a package'),
('os.path', br'loader.*cannot handle'),
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_importlib/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,12 @@ def test_find_relative_module_missing_package(self):
self.assertNotIn(name, sorted(sys.modules))
self.assertNotIn(fullname, sorted(sys.modules))

def test_find_submodule_in_module(self):
# ModuleNotFoundError raised when a module is specified as
# a parent instead of a package.
with self.assertRaises(ModuleNotFoundError):
self.util.find_spec('module.name')


(Frozen_FindSpecTests,
Source_FindSpecTests
Expand Down
4 changes: 4 additions & 0 deletions Misc/NEWS
6D8E
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ Library
- bpo-30149: inspect.signature() now supports callables with
variable-argument parameters wrapped with partialmethod.
Patch by Dong-hee Na.

- bpo-30436: importlib.find_spec() raises ModuleNotFoundError instead of
AttributeError if the specified parent module is not a package
(i.e. lacks a __path__ attribute).

- bpo-30301: Fix AttributeError when using SimpleQueue.empty() under
*spawn* and *forkserver* start methods.
Expand Down
0