Skip to content

Commit c71b5df

Browse files
github-actions[bot]akhilramkeenicoddemus
authored
[7.4.x] Add child modules as attributes of parent modules. (#11163)
* [7.4.x] Add child modules as attributes of parent modules. * Update 10337.bugfix.rst --------- Co-authored-by: akhilramkee <[email protected]> Co-authored-by: Bruno Oliveira <[email protected]>
1 parent d539518 commit c71b5df

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

changelog/10337.bugfix.rst

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed bug where fake intermediate modules generated by ``--import-mode=importlib`` would not include the
2+
child modules as attributes of the parent modules.

src/_pytest/pathlib.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,9 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) ->
635635
otherwise "src.tests.test_foo" is not importable by ``__import__``.
636636
"""
637637
module_parts = module_name.split(".")
638+
child_module: Union[ModuleType, None] = None
639+
module: Union[ModuleType, None] = None
640+
child_name: str = ""
638641
while module_name:
639642
if module_name not in modules:
640643
try:
@@ -644,13 +647,22 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) ->
644647
# ourselves to fall back to creating a dummy module.
645648
if not sys.meta_path:
646649
raise ModuleNotFoundError
647-
importlib.import_module(module_name)
650+
module = importlib.import_module(module_name)
648651
except ModuleNotFoundError:
649652
module = ModuleType(
650653
module_name,
651654
doc="Empty module created by pytest's importmode=importlib.",
652655
)
656+
else:
657+
module = modules[module_name]
658+
if child_module:
659+
# Add child attribute to the parent that can reference the child
660+
# modules.
661+
if not hasattr(module, child_name):
662+
setattr(module, child_name, child_module)
653663
modules[module_name] = module
664+
# Keep track of the child module while moving up the tree.
665+
child_module, child_name = module, module_name.rpartition(".")[-1]
654666
module_parts.pop(-1)
655667
module_name = ".".join(module_parts)
656668

testing/test_pathlib.py

+12
Original file line numberDiff line numberDiff line change
@@ -603,3 +603,15 @@ def test_insert_missing_modules(
603603
modules = {}
604604
insert_missing_modules(modules, "")
605605
assert modules == {}
606+
607+
def test_parent_contains_child_module_attribute(
608+
self, monkeypatch: MonkeyPatch, tmp_path: Path
609+
):
610+
monkeypatch.chdir(tmp_path)
611+
# Use 'xxx' and 'xxy' as parent names as they are unlikely to exist and
612+
# don't end up being imported.
613+
modules = {"xxx.tests.foo": ModuleType("xxx.tests.foo")}
614+
insert_missing_modules(modules, "xxx.tests.foo")
615+
assert sorted(modules) == ["xxx", "xxx.tests", "xxx.tests.foo"]
616+
assert modules["xxx"].tests is modules["xxx.tests"]
617+
assert modules["xxx.tests"].foo is modules["xxx.tests.foo"]

0 commit comments

Comments
 (0)