Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e9d7f88

Browse files
authored
bpo-44061: Fix pkgutil.iter_modules regression when passed a pathlib.Path object (GH-25964)
1 parent 8563a70 commit e9d7f88

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

Lib/pkgutil.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ def get_importer(path_item):
413413
The cache (or part of it) can be cleared manually if a
414414
rescan of sys.path_hooks is necessary.
415415
"""
416+
path_item = os.fsdecode(path_item)
416417
try:
417418
importer = sys.path_importer_cache[path_item]
418419
except KeyError:

Lib/test/test_pkgutil.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from pathlib import Path
12
from test.support import run_unittest
23
from test.support.import_helper import unload, CleanImport
34
from test.support.warnings_helper import check_warnings
@@ -92,6 +93,45 @@ def test_getdata_zipfile(self):
9293

9394
del sys.modules[pkg]
9495

96+
def test_issue44061_iter_modules(self):
97+
#see: issue44061
98+
zip = 'test_getdata_zipfile.zip'
99+
pkg = 'test_getdata_zipfile'
100+
101+
# Include a LF and a CRLF, to test that binary data is read back
102+
RESOURCE_DATA = b'Hello, world!\nSecond line\r\nThird line'
103+
104+
# Make a package with some resources
105+
zip_file = os.path.join(self.dirname, zip)
106+
z = zipfile.ZipFile(zip_file, 'w')
107+
108+
# Empty init.py
109+
z.writestr(pkg + '/__init__.py', "")
110+
# Resource files, res.txt
111+
z.writestr(pkg + '/res.txt', RESOURCE_DATA)
112+
z.close()
113+
114+
# Check we can read the resources
115+
sys.path.insert(0, zip_file)
116+
try:
117+
res = pkgutil.get_data(pkg, 'res.txt')
118+
self.assertEqual(res, RESOURCE_DATA)
119+
120+
# make sure iter_modules accepts Path objects
121+
names = []
122+
for moduleinfo in pkgutil.iter_modules([Path(zip_file)]):
123+
self.assertIsInstance(moduleinfo, pkgutil.ModuleInfo)
124+
names.append(moduleinfo.name)
125+
self.assertEqual(names, [pkg])
126+
finally:
127+
del sys.path[0]
128+
sys.modules.pop(pkg, None)
129+
130+
# assert path must be None or list of paths
131+
expected_msg = "path must be None or list of paths to look for modules in"
132+
with self.assertRaisesRegex(ValueError, expected_msg):
133+
list(pkgutil.iter_modules("invalid_path"))
134+
95135
def test_unreadable_dir_on_syspath(self):
96136
# issue7367 - walk_packages failed if unreadable dir on sys.path
97137
package_name = "unreadable_package"
@@ -574,6 +614,12 @@ def test_get_importer_avoids_emulation(self):
574614
self.assertIsNone(pkgutil.get_importer("*??"))
575615
self.assertEqual(len(w.warnings), 0)
576616

617+
def test_issue44061(self):
618+
try:
619+
pkgutil.get_importer(Path("/home"))
620+
except AttributeError:
621+
self.fail("Unexpected AttributeError when calling get_importer")
622+
577623
def test_iter_importers_avoids_emulation(self):
578624
with check_warnings() as w:
579625
for importer in pkgutil.iter_importers(): pass
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix regression in previous release when calling :func:`pkgutil.iter_modules`
2+
with a list of :class:`pathlib.Path` objects

0 commit comments

Comments
 (0)