Skip to content

Commit

Permalink
bpo-44061: Fix pkgutil.iter_modules regression when passed a pathlib.…
Browse files Browse the repository at this point in the history
…Path object (GH-25964)
  • Loading branch information
miguendes committed May 11, 2021
1 parent 8563a70 commit e9d7f88
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
1 change: 1 addition & 0 deletions Lib/pkgutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,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:
Expand Down
46 changes: 46 additions & 0 deletions Lib/test/test_pkgutil.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from pathlib import Path
from test.support import run_unittest
from test.support.import_helper import unload, CleanImport
from test.support.warnings_helper import check_warnings
Expand Down Expand Up @@ -92,6 +93,45 @@ def test_getdata_zipfile(self):

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"
Expand Down Expand Up @@ -574,6 +614,12 @@ def test_get_importer_avoids_emulation(self):
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix regression in previous release when calling :func:`pkgutil.iter_modules`
with a list of :class:`pathlib.Path` objects

0 comments on commit e9d7f88

Please sign in to comment.