From: Ɓukasz Langa Date: Wed, 12 May 2021 10:18:07 +0000 (+0200) Subject: [3.8] bpo-44061: Fix pkgutil.iter_modules regression when passed a pathlib.Path objec... X-Git-Tag: v3.8.11~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4844abdd700120120fc76c29d911bcb547700baf;p=thirdparty%2FPython%2Fcpython.git [3.8] bpo-44061: Fix pkgutil.iter_modules regression when passed a pathlib.Path object (GH-25964). (GH-26056) (cherry picked from commit e9d7f88d5643f7e6387bf994c130503766d7eb92) Co-authored-by: Miguel Brito <5544985+miguendes@users.noreply.github.com> --- diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 8474a773e7c7..3344d9dac98a 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -411,6 +411,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 2887ce6cc055..a7a14969a93b 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -1,4 +1,5 @@ from test.support import run_unittest, unload, check_warnings, CleanImport +from pathlib import Path import unittest import sys import importlib @@ -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" @@ -480,6 +520,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 000000000000..e41f285fae94 --- /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