Add child modules as attributes of parent modules.

Failing to add child modules as attributes of parent module will
prevent them from being accessible through parent module.
This commit is contained in:
Akhilesh 2022-10-04 22:45:34 +05:30 committed by Bruno Oliveira
parent ba60649680
commit 46c0a11ffa
2 changed files with 25 additions and 1 deletions

View File

@ -633,6 +633,9 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) ->
otherwise "src.tests.test_foo" is not importable by ``__import__``. otherwise "src.tests.test_foo" is not importable by ``__import__``.
""" """
module_parts = module_name.split(".") module_parts = module_name.split(".")
child_module: Union[ModuleType, None] = None
module: Union[ModuleType, None] = None
child_name: str = ""
while module_name: while module_name:
if module_name not in modules: if module_name not in modules:
try: try:
@ -642,13 +645,22 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) ->
# ourselves to fall back to creating a dummy module. # ourselves to fall back to creating a dummy module.
if not sys.meta_path: if not sys.meta_path:
raise ModuleNotFoundError raise ModuleNotFoundError
importlib.import_module(module_name) module = importlib.import_module(module_name)
except ModuleNotFoundError: except ModuleNotFoundError:
module = ModuleType( module = ModuleType(
module_name, module_name,
doc="Empty module created by pytest's importmode=importlib.", doc="Empty module created by pytest's importmode=importlib.",
) )
else:
module = modules[module_name]
if child_module:
# Add child attribute to the parent that can reference the child
# modules.
if not hasattr(module, child_name):
setattr(module, child_name, child_module)
modules[module_name] = module modules[module_name] = module
# Keep track of the child module while moving up the tree.
child_module, child_name = module, module_name.rpartition(".")[-1]
module_parts.pop(-1) module_parts.pop(-1)
module_name = ".".join(module_parts) module_name = ".".join(module_parts)

View File

@ -592,3 +592,15 @@ class TestImportLibMode:
modules = {} modules = {}
insert_missing_modules(modules, "") insert_missing_modules(modules, "")
assert modules == {} assert modules == {}
def test_parent_contains_child_module_attribute(
self, monkeypatch: MonkeyPatch, tmp_path: Path
):
monkeypatch.chdir(tmp_path)
# Use 'xxx' and 'xxy' as parent names as they are unlikely to exist and
# don't end up being imported.
modules = {"xxx.tests.foo": ModuleType("xxx.tests.foo")}
insert_missing_modules(modules, "xxx.tests.foo")
assert sorted(modules) == ["xxx", "xxx.tests", "xxx.tests.foo"]
assert modules["xxx"].tests == modules["xxx.tests"]
assert modules["xxx.tests"].foo == modules["xxx.tests.foo"]