Verify that `_import_module_using_spec` can obtain a spec based on the path, thereby enabling the import. When importing, not only the target module is imported, but also the parent modules are recursively imported.
(
self, b_is_package, insert_modules, tmp_path: Path
)
| 810 | @pytest.mark.parametrize("b_is_package", [True, False]) |
| 811 | @pytest.mark.parametrize("insert_modules", [True, False]) |
| 812 | def test_import_module_using_spec( |
| 813 | self, b_is_package, insert_modules, tmp_path: Path |
| 814 | ): |
| 815 | """ |
| 816 | Verify that `_import_module_using_spec` can obtain a spec based on the path, thereby enabling the import. |
| 817 | When importing, not only the target module is imported, but also the parent modules are recursively imported. |
| 818 | """ |
| 819 | file_path = tmp_path / "a/b/c/demo.py" |
| 820 | file_path.parent.mkdir(parents=True) |
| 821 | file_path.write_text("my_name='demo'", encoding="utf-8") |
| 822 | |
| 823 | if b_is_package: |
| 824 | (tmp_path / "a/b/__init__.py").write_text( |
| 825 | "my_name='b.__init__'", encoding="utf-8" |
| 826 | ) |
| 827 | |
| 828 | mod = _import_module_using_spec( |
| 829 | "a.b.c.demo", |
| 830 | file_path, |
| 831 | insert_modules=insert_modules, |
| 832 | ) |
| 833 | |
| 834 | # target module is imported |
| 835 | assert mod is not None |
| 836 | assert spec_matches_module_path(mod.__spec__, file_path) is True |
| 837 | |
| 838 | mod_demo = sys.modules["a.b.c.demo"] |
| 839 | assert "demo.py" in str(mod_demo) |
| 840 | assert mod_demo.my_name == "demo" # Imported and available for use |
| 841 | |
| 842 | # parent modules are recursively imported. |
| 843 | mod_a = sys.modules["a"] |
| 844 | mod_b = sys.modules["a.b"] |
| 845 | mod_c = sys.modules["a.b.c"] |
| 846 | |
| 847 | assert mod_a.b is mod_b |
| 848 | assert mod_a.b.c is mod_c |
| 849 | assert mod_a.b.c.demo is mod_demo |
| 850 | |
| 851 | assert "namespace" in str(mod_a).lower() |
| 852 | assert "namespace" in str(mod_c).lower() |
| 853 | |
| 854 | # Compatibility package and namespace package. |
| 855 | if b_is_package: |
| 856 | assert "namespace" not in str(mod_b).lower() |
| 857 | assert "__init__.py" in str(mod_b).lower() # Imported __init__.py |
| 858 | assert mod_b.my_name == "b.__init__" # Imported and available for use |
| 859 | |
| 860 | else: |
| 861 | assert "namespace" in str(mod_b).lower() |
| 862 | with pytest.raises(AttributeError): # Not imported __init__.py |
| 863 | assert mod_b.my_name |
| 864 | |
| 865 | def test_parent_contains_child_module_attribute( |
| 866 | self, monkeypatch: MonkeyPatch, tmp_path: Path |
nothing calls this directly
no test coverage detected