summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Cannon <brettcannon@users.noreply.github.com>2019-03-22 22:16:50 (GMT)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-03-22 22:16:50 (GMT)
commit5086589305ff5538709856b27314b68f06ae93db (patch)
tree53f1842d1dc8c9ae109dca4ccfc43941b5de320d
parentdd7c4ceed90792f711347024852d4cf883a9ab9e (diff)
downloadcpython-5086589305ff5538709856b27314b68f06ae93db.zip
cpython-5086589305ff5538709856b27314b68f06ae93db.tar.gz
cpython-5086589305ff5538709856b27314b68f06ae93db.tar.bz2
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
-rw-r--r--Lib/pyclbr.py7
-rw-r--r--Lib/test/test_pyclbr.py24
-rw-r--r--Misc/NEWS.d/next/Library/2019-03-15-13-54-07.bpo-36298.amEVK2.rst2
3 files changed, 29 insertions, 4 deletions
diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py
index 2c798df..8fd0523 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 9e970d9..839c58f 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -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
index 0000000..14be079
--- /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.