Skip to content

Commit 4844abd

Browse files
ambvmiguendes
andauthored
[3.8] bpo-44061: Fix pkgutil.iter_modules regression when passed a pathlib.Path object (pythonGH-25964). (pythonGH-26056)
(cherry picked from commit e9d7f88) Co-authored-by: Miguel Brito <5544985+miguendes@users.noreply.github.com>
1 parent 378211f commit 4844abd

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

Lib/pkgutil.py

+1
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ def get_importer(path_item):
411411
The cache (or part of it) can be cleared manually if a
412412
rescan of sys.path_hooks is necessary.
413413
"""
414+
path_item = os.fsdecode(path_item)
414415
try:
415416
importer = sys.path_importer_cache[path_item]
416417
except KeyError:

Lib/test/test_pkgutil.py

+46
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from test.support import run_unittest, unload, check_warnings, CleanImport
2+
from pathlib import Path
23
import unittest
34
import sys
45
import importlib
@@ -90,6 +91,45 @@ def test_getdata_zipfile(self):
9091

9192
del sys.modules[pkg]
9293

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

523+
def test_issue44061(self):
524+
try:
525+
pkgutil.get_importer(Path("/home"))
526+
except AttributeError:
527+
self.fail("Unexpected AttributeError when calling get_importer")
528+
483529
def test_iter_importers_avoids_emulation(self):
484530
with check_warnings() as w:
485531
for importer in pkgutil.iter_importers(): pass
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)