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

Skip to content

bpo-36053 fix pkgutil.walk_packages #11956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Lib/pkgutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ def seen(p, m={}):
yield info

if info.ispkg:
loader = info.module_finder.find_module(info.name)
try:
__import__(info.name)
module = loader.load_module(info.name)
except ImportError:
if onerror is not None:
onerror(info.name)
Expand All @@ -99,7 +100,7 @@ def seen(p, m={}):
else:
raise
else:
path = getattr(sys.modules[info.name], '__path__', None) or []
path = module.__path__

# don't traverse path items we've seen before
path = [p for p in path if not seen(p)]
Expand Down
37 changes: 36 additions & 1 deletion Lib/test/test_pkgutil.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from test.support import run_unittest, unload, check_warnings, CleanImport
from test.support import forget, run_unittest, unload, check_warnings, CleanImport
import unittest
import sys
import importlib
Expand Down Expand Up @@ -176,6 +176,41 @@ def test_walkpackages_zipfile(self):
continue
del sys.modules[pkg]

def test_walk_packages_with_same_package_name_in_pythonpath(self):
pkg1 = 'test_walk_packages_with_same_package_name_in_pythonpath'
pkg1_dir = os.path.join(self.dirname, pkg1)
os.mkdir(pkg1_dir)
f = open(os.path.join(pkg1_dir, '__init__.py'), "wb")
f.close()
os.mkdir(os.path.join(pkg1_dir, 'same_name'))
f = open(os.path.join(pkg1_dir, 'same_name', '__init__.py'), "wb")
f.close()
f = open(os.path.join(pkg1_dir, 'same_name', 'mod.py'), "wb")
f.close()

# Add another package in the path, with the same name as the one inside pkg1
pkg2 = 'same_name'
pkg2_dir = os.path.join(self.dirname, pkg2)
os.mkdir(pkg2_dir)
f = open(os.path.join(pkg2_dir, '__init__.py'), "wb")
f.close()
os.mkdir(os.path.join(pkg2_dir, 'test_same_name'))
f = open(os.path.join(pkg2_dir, 'test_same_name', '__init__.py'), "wb")
f.close()
f = open(os.path.join(pkg2_dir, 'test_same_name', 'another_mod.py'), "wb")
f.close()

expected = [
'same_name',
'same_name.mod'
]

for pkg in expected:
self.addCleanup(forget, pkg)

actual = [e[1] for e in pkgutil.walk_packages([os.path.join(self.dirname, pkg1)])]
self.assertEqual(actual, expected)

def test_walk_packages_raises_on_string_or_bytes_input(self):

str_input = 'test_dir'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix ``pkgutil.walk_packages()`` jumping outside given path if a package with the same name is available inside ``sys.path``. Patch by Piotr Karkut.