]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-36298: Raise ModuleNotFoundError in pyclbr when a module can't be found (GH-12358)
authorBrett Cannon <brettcannon@users.noreply.github.com>
Fri, 22 Mar 2019 22:16:50 +0000 (15:16 -0700)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 22 Mar 2019 22:16:50 +0000 (15:16 -0700)
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

Lib/pyclbr.py
Lib/test/test_pyclbr.py
Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst [new file with mode: 0644]

index 2c798df233b8ebd849cbf818f5aebc5d0561363f..8fd0523b7e3b96b0cdfe5b975f0557322dbc1fc9 100644 (file)
@@ -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)
index 9e970d9df041b858c81815c4d0109e3e496265f1..839c58f0fde5be1424bd47c6e0ed836ec91f9fe5 100644 (file)
@@ -10,6 +10,7 @@ from types import FunctionType, MethodType, BuiltinFunctionType
 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 @@ class PyclbrTest(TestCase):
         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 (file)
index 0000000..14be079
--- /dev/null
@@ -0,0 +1,2 @@
+Raise ModuleNotFoundError in pyclbr when a module can't be found.
+Thanks to 'mental' for the bug report.