aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Doc/library/importlib.rst8
-rw-r--r--Lib/importlib/__init__.py2
-rw-r--r--Lib/test/test_importlib/test_api.py14
-rw-r--r--Misc/NEWS3
4 files changed, 26 insertions, 1 deletions
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 1bd11f45ff1..5360d3c11d3 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -90,7 +90,7 @@ Functions
Find the loader for a module, optionally within the specified *path*. If the
module is in :attr:`sys.modules`, then ``sys.modules[name].__loader__`` is
- returned (unless the loader would be ``None``, in which case
+ returned (unless the loader would be ``None`` or is not set, in which case
:exc:`ValueError` is raised). Otherwise a search using :attr:`sys.meta_path`
is done. ``None`` is returned if no loader is found.
@@ -99,6 +99,12 @@ Functions
will need to import all parent packages of the submodule and use the correct
argument to *path*.
+ .. versionadded:: 3.3
+
+ .. versionchanged:: 3.4
+ If ``__loader__`` is not set, raise :exc:`ValueError`, just like when the
+ attribute is set to ``None``.
+
.. function:: invalidate_caches()
Invalidate the internal caches of finders stored at
diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py
index 22c90f24a7e..d07f02ed746 100644
--- a/Lib/importlib/__init__.py
+++ b/Lib/importlib/__init__.py
@@ -68,6 +68,8 @@ def find_loader(name, path=None):
return loader
except KeyError:
pass
+ except AttributeError:
+ raise ValueError('{}.__loader__ is not set'.format(name))
return _bootstrap._find_module(name, path)
diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py
index f66e257ee99..ac88b2bf9c1 100644
--- a/Lib/test/test_importlib/test_api.py
+++ b/Lib/test/test_importlib/test_api.py
@@ -116,6 +116,20 @@ class FindLoaderTests(unittest.TestCase):
with self.assertRaises(ValueError):
importlib.find_loader(name)
+ def test_sys_modules_loader_is_not_set(self):
+ # Should raise ValueError
+ # Issue #17099
+ name = 'some_mod'
+ with util.uncache(name):
+ module = imp.new_module(name)
+ try:
+ del module.__loader__
+ except AttributeError:
+ pass
+ sys.modules[name] = module
+ with self.assertRaises(ValueError):
+ importlib.find_loader(name)
+
def test_success(self):
# Return the loader found on sys.meta_path.
name = 'some_mod'
diff --git a/Misc/NEWS b/Misc/NEWS
index 06e22323758..c5a58775e27 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -280,6 +280,9 @@ Core and Builtins
Library
-------
+- Issue #17099: Have importlib.find_loader() raise ValueError when __loader__
+ is not set, harmonizing with what happens when the attribute is set to None.
+
- Expose the O_PATH constant in the os module if it is available.
- Issue #17368: Fix an off-by-one error in the Python JSON decoder that caused