diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 7f01c011b..0ef8d094f 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -737,34 +737,31 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) -> otherwise "src.tests.test_foo" is not importable by ``__import__``. """ module_parts = module_name.split(".") - child_module: Union[ModuleType, None] = None - module: Union[ModuleType, None] = None - child_name: str = "" while module_name: - if module_name not in modules: - try: - # If sys.meta_path is empty, calling import_module will issue - # a warning and raise ModuleNotFoundError. To avoid the - # warning, we check sys.meta_path explicitly and raise the error - # ourselves to fall back to creating a dummy module. - if not sys.meta_path: - raise ModuleNotFoundError - module = importlib.import_module(module_name) - except ModuleNotFoundError: - module = ModuleType( - module_name, - doc="Empty module created by pytest's importmode=importlib.", - ) - else: - module = modules[module_name] - if child_module: + parent_module_name, _, child_name = module_name.rpartition(".") + if parent_module_name: + parent_module = modules.get(parent_module_name) + if parent_module is None: + try: + # If sys.meta_path is empty, calling import_module will issue + # a warning and raise ModuleNotFoundError. To avoid the + # warning, we check sys.meta_path explicitly and raise the error + # ourselves to fall back to creating a dummy module. + if not sys.meta_path: + raise ModuleNotFoundError + parent_module = importlib.import_module(parent_module_name) + except ModuleNotFoundError: + parent_module = ModuleType( + module_name, + doc="Empty module created by pytest's importmode=importlib.", + ) + modules[parent_module_name] = parent_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 - # Keep track of the child module while moving up the tree. - child_module, child_name = module, module_name.rpartition(".")[-1] + if not hasattr(parent_module, child_name): + setattr(parent_module, child_name, modules[module_name]) + module_parts.pop(-1) module_name = ".".join(module_parts)