[Python-checkins] bpo-36298: Raise ModuleNotFoundError in pyclbr when a module can't be found (GH-12358)

Miss Islington (bot) webhook-mailer at python.org
Fri Mar 22 18:16:53 EDT 2019


https://github.com/python/cpython/commit/5086589305ff5538709856b27314b68f06ae93db
commit: 5086589305ff5538709856b27314b68f06ae93db
branch: master
author: Brett Cannon <brettcannon at users.noreply.github.com>
committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
date: 2019-03-22T15:16:50-07:00
summary:

bpo-36298: Raise ModuleNotFoundError in pyclbr when a module can't be found (GH-12358)



Before, an `AttributeError` was raised due to trying to access an attribute that exists on specs but having received `None` instead for a non-existent module.


https://bugs.python.org/issue36298

files:
A Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst
M Lib/pyclbr.py
M Lib/test/test_pyclbr.py

diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py
index 2c798df233b8..8fd0523b7e3b 100644
--- a/Lib/pyclbr.py
+++ b/Lib/pyclbr.py
@@ -160,17 +160,20 @@ def _readmodule(module, path, inpackage=None):
     else:
         search_path = path + sys.path
     spec = importlib.util._find_spec_from_path(fullmodule, search_path)
+    if spec is None:
+        raise ModuleNotFoundError(f"no module named {fullmodule!r}", name=fullmodule)
     _modules[fullmodule] = tree
     # Is module a package?
     if spec.submodule_search_locations is not None:
         tree['__path__'] = spec.submodule_search_locations
     try:
         source = spec.loader.get_source(fullmodule)
-        if source is None:
-            return tree
     except (AttributeError, ImportError):
         # If module is not Python source, we cannot do anything.
         return tree
+    else:
+        if source is None:
+            return tree
 
     fname = spec.loader.get_filename(fullmodule)
     return _create_tree(fullmodule, path, fname, source, tree, inpackage)
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 9e970d9df041..839c58f0fde5 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -10,6 +10,7 @@
 import pyclbr
 from unittest import TestCase, main as unittest_main
 from test import support
+from test.test_importlib import util as test_importlib_util
 from functools import partial
 
 StaticMethodType = type(staticmethod(lambda: None))
@@ -235,11 +236,30 @@ def test_others(self):
         cm('email.parser')
         cm('test.test_pyclbr')
 
-    def test_issue_14798(self):
+
+class ReadmoduleTests(TestCase):
+
+    def setUp(self):
+        self._modules = pyclbr._modules.copy()
+
+    def tearDown(self):
+        pyclbr._modules = self._modules
+
+
+    def test_dotted_name_not_a_package(self):
         # test ImportError is raised when the first part of a dotted name is
-        # not a package
+        # not a package.
+        #
+        # Issue #14798.
         self.assertRaises(ImportError, pyclbr.readmodule_ex, 'asyncore.foo')
 
+    def test_module_has_no_spec(self):
+        module_name = "doesnotexist"
+        assert module_name not in pyclbr._modules
+        with test_importlib_util.uncache(module_name):
+            with self.assertRaises(ModuleNotFoundError):
+                pyclbr.readmodule_ex(module_name)
+
 
 if __name__ == "__main__":
     unittest_main()
diff --git a/Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst b/Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst
new file mode 100644
index 000000000000..14be079ddb92
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst
@@ -0,0 +1,2 @@
+Raise ModuleNotFoundError in pyclbr when a module can't be found.
+Thanks to 'mental' for the bug report.



More information about the Python-checkins mailing list