Used by ``import_path`` to create intermediate modules when using mode=importlib. When we want to import a module as "src.tests.test_foo" for example, we need to create empty modules "src" and "src.tests" after inserting "src.tests.test_foo", otherwise "src.tests.test_foo" is not i
(modules: dict[str, ModuleType], module_name: str)
| 790 | |
| 791 | |
| 792 | def insert_missing_modules(modules: dict[str, ModuleType], module_name: str) -> None: |
| 793 | """ |
| 794 | Used by ``import_path`` to create intermediate modules when using mode=importlib. |
| 795 | |
| 796 | When we want to import a module as "src.tests.test_foo" for example, we need |
| 797 | to create empty modules "src" and "src.tests" after inserting "src.tests.test_foo", |
| 798 | otherwise "src.tests.test_foo" is not importable by ``__import__``. |
| 799 | """ |
| 800 | module_parts = module_name.split(".") |
| 801 | while module_name: |
| 802 | parent_module_name, _, child_name = module_name.rpartition(".") |
| 803 | if parent_module_name: |
| 804 | parent_module = modules.get(parent_module_name) |
| 805 | if parent_module is None: |
| 806 | try: |
| 807 | # If sys.meta_path is empty, calling import_module will issue |
| 808 | # a warning and raise ModuleNotFoundError. To avoid the |
| 809 | # warning, we check sys.meta_path explicitly and raise the error |
| 810 | # ourselves to fall back to creating a dummy module. |
| 811 | if not sys.meta_path: |
| 812 | raise ModuleNotFoundError |
| 813 | parent_module = importlib.import_module(parent_module_name) |
| 814 | except ModuleNotFoundError: |
| 815 | parent_module = ModuleType( |
| 816 | module_name, |
| 817 | doc="Empty module created by pytest's importmode=importlib.", |
| 818 | ) |
| 819 | modules[parent_module_name] = parent_module |
| 820 | |
| 821 | # Add child attribute to the parent that can reference the child |
| 822 | # modules. |
| 823 | if not hasattr(parent_module, child_name): |
| 824 | setattr(parent_module, child_name, modules[module_name]) |
| 825 | |
| 826 | module_parts.pop(-1) |
| 827 | module_name = ".".join(module_parts) |
| 828 | |
| 829 | |
| 830 | def resolve_package_path(path: Path) -> Path | None: |