diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index def5fa94b2b..5f303291cf2 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -504,6 +504,9 @@ def import_path( mod = importlib.util.module_from_spec(spec) sys.modules[module_name] = mod spec.loader.exec_module(mod) # type: ignore[union-attr] + if path.is_dir() and path.joinpath("__init__.py").exists(): + mod.__path__ = [str(path)] + insert_missing_modules(sys.modules, module_name) insert_missing_modules(sys.modules, module_name) return mod diff --git a/testing/test_config.py b/testing/test_config.py index 8013966f071..4eea5596ca1 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -476,6 +476,27 @@ def test_parsing_again_fails(self, pytester: Pytester) -> None: config = pytester.parseconfig() pytest.raises(AssertionError, lambda: config.parse([])) + def test_import_mode_importlib_with_conftest_and_pythonpath(self, pytester: Pytester): + pytester.makepyfile(tests="__init__.py") + pytester.makepyfile(tests_conftest="# Existence of this file breaks package discovery") + pytester.makepyfile(tests_subpath="__init__.py") + pytester.makepyfile(tests_subpath_helper="# Empty helper file") + test_file_content = textwrap.dedent(""" + import tests.subpath.helper + def test_something(): + assert True + """) + pytester.makepyfile(tests_subpath_test_something=test_file_content) + pytester.makefile(".ini", pytest=""" + [tool:pytest] + pythonpath = . + addopts = --import-mode importlib + """) + + result = pytester.runpytest() + # The test should pass indicating that tests.subpath.helper was imported correctly + assert result.ret == 0 + def test_explicitly_specified_config_file_is_loaded( self, pytester: Pytester ) -> None: