-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Closed as not planned
Closed as not planned
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
Description
Bug report
Bug description:
As the title says, pkgutil.walk_packages
is using mutable default (a dictionary) to remember modules it already seen.
Code link.
This may lead to hard-to-track bugs, when you try to import a package with the same name, but in different folder.
Example code where this issue could break stuff (I'm actually using something similar in my tests):
import importlib
import pkgutil
import sys
import tempfile
from pathlib import Path
DUMMY_MODULE = """
def hello_world():
return "Hello, World!"
"""
class MyLoader:
def __init__(self, path):
self.path = path
self.available_modules = {}
def load_module(self, fullname):
if fullname in self.available_modules:
return self.available_modules[fullname]
def discover_modules(self):
sys.path.append(str(self.path))
for _, module_name, is_pkg in pkgutil.walk_packages([self.path]):
if not is_pkg:
module = importlib.import_module(module_name)
self.available_modules[module_name] = module
sys.path.remove(str(self.path))
def do_test():
print("Running test")
with tempfile.TemporaryDirectory() as tmp_dir:
tmp_path = Path(tmp_dir)
package_name = "my_package"
package_path = tmp_path / package_name
package_path.mkdir()
module_path = package_path / "my_module.py"
init_path = package_path / "__init__.py"
init_path.touch()
with module_path.open("w") as f:
f.write(DUMMY_MODULE)
loader = MyLoader(path=tmp_path)
loader.discover_modules()
module = loader.load_module("my_package.my_module")
assert module.hello_world() == "Hello, World!"
print("Test passed")
if __name__ == "__main__":
do_test()
do_test() # This will fail
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory