diff options
author | Steve Dower <steve.dower@python.org> | 2021-05-12 09:48:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-12 09:48:50 (GMT) |
commit | 0cb9775a85a051556461ea9c3089244601b7d4f8 (patch) | |
tree | 6674e498410459874c195ba3ea25045fe11e0842 | |
parent | 6c190b5ae5887d592bc8915148440a63da8b7cdd (diff) | |
download | cpython-0cb9775a85a051556461ea9c3089244601b7d4f8.zip cpython-0cb9775a85a051556461ea9c3089244601b7d4f8.tar.gz cpython-0cb9775a85a051556461ea9c3089244601b7d4f8.tar.bz2 |
bpo-44061: Fix pkgutil.iter_modules regression when passed a pathlib.Path object (GH-25964) (GH-26052)
Co-authored-by: Miguel Brito <5544985+miguendes@users.noreply.github.com>
-rw-r--r-- | Lib/pkgutil.py | 1 | ||||
-rw-r--r-- | Lib/test/test_pkgutil.py | 46 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-05-07-08-39-23.bpo-44061.MvElG6.rst | 2 |
3 files changed, 49 insertions, 0 deletions
diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 4c18467..1d623e6 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -412,6 +412,7 @@ def get_importer(path_item): The cache (or part of it) can be cleared manually if a rescan of sys.path_hooks is necessary. """ + path_item = os.fsdecode(path_item) try: importer = sys.path_importer_cache[path_item] except KeyError: diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py index b162f99..54725dc 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -1,3 +1,4 @@ +from pathlib import Path from test.support import run_unittest, unload, check_warnings, CleanImport import unittest import sys @@ -90,6 +91,45 @@ class PkgutilTests(unittest.TestCase): del sys.modules[pkg] + def test_issue44061_iter_modules(self): + #see: issue44061 + zip = 'test_getdata_zipfile.zip' + pkg = 'test_getdata_zipfile' + + # Include a LF and a CRLF, to test that binary data is read back + RESOURCE_DATA = b'Hello, world!\nSecond line\r\nThird line' + + # Make a package with some resources + zip_file = os.path.join(self.dirname, zip) + z = zipfile.ZipFile(zip_file, 'w') + + # Empty init.py + z.writestr(pkg + '/__init__.py', "") + # Resource files, res.txt + z.writestr(pkg + '/res.txt', RESOURCE_DATA) + z.close() + + # Check we can read the resources + sys.path.insert(0, zip_file) + try: + res = pkgutil.get_data(pkg, 'res.txt') + self.assertEqual(res, RESOURCE_DATA) + + # make sure iter_modules accepts Path objects + names = [] + for moduleinfo in pkgutil.iter_modules([Path(zip_file)]): + self.assertIsInstance(moduleinfo, pkgutil.ModuleInfo) + names.append(moduleinfo.name) + self.assertEqual(names, [pkg]) + finally: + del sys.path[0] + sys.modules.pop(pkg, None) + + # assert path must be None or list of paths + expected_msg = "path must be None or list of paths to look for modules in" + with self.assertRaisesRegex(ValueError, expected_msg): + list(pkgutil.iter_modules("invalid_path")) + def test_unreadable_dir_on_syspath(self): # issue7367 - walk_packages failed if unreadable dir on sys.path package_name = "unreadable_package" @@ -571,6 +611,12 @@ class ImportlibMigrationTests(unittest.TestCase): self.assertIsNone(pkgutil.get_importer("*??")) self.assertEqual(len(w.warnings), 0) + def test_issue44061(self): + try: + pkgutil.get_importer(Path("/home")) + except AttributeError: + self.fail("Unexpected AttributeError when calling get_importer") + def test_iter_importers_avoids_emulation(self): with check_warnings() as w: for importer in pkgutil.iter_importers(): pass diff --git a/Misc/NEWS.d/next/Library/2021-05-07-08-39-23.bpo-44061.MvElG6.rst b/Misc/NEWS.d/next/Library/2021-05-07-08-39-23.bpo-44061.MvElG6.rst new file mode 100644 index 0000000..e41f285 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-05-07-08-39-23.bpo-44061.MvElG6.rst @@ -0,0 +1,2 @@ +Fix regression in previous release when calling :func:`pkgutil.iter_modules` +with a list of :class:`pathlib.Path` objects |