[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 <31619526+akhilramkee@users.noreply.github.com> Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
This commit is contained in:
parent
d53951836d
commit
c71b5df734
|
@ -0,0 +1,2 @@
|
||||||
|
Fixed bug where fake intermediate modules generated by ``--import-mode=importlib`` would not include the
|
||||||
|
child modules as attributes of the parent modules.
|
|
@ -635,6 +635,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:
|
||||||
|
@ -644,13 +647,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)
|
||||||
|
|
||||||
|
|
|
@ -603,3 +603,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 is modules["xxx.tests"]
|
||||||
|
assert modules["xxx.tests"].foo is modules["xxx.tests.foo"]
|
||||||
|
|
Loading…
Reference in New Issue