Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/14048.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed ``--pyargs`` not finding modules in the current directory when running pytest from a subdirectory, particularly when using tox.

The invocation directory is now added to ``sys.path`` early during initialization when ``--pyargs`` is used, ensuring that ``importlib.util.find_spec()`` can locate modules in the current working directory.
8 changes: 8 additions & 0 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,14 @@ def pytest_load_initial_conftests(self, early_config: Config) -> None:
# early_config.args it not set yet. But we need it for
# discovering the initial conftests. So "pre-run" the logic here.
# It will be done for real in `parse()`.

# When using --pyargs, ensure invocation_dir is in sys.path so that
# modules in the current directory can be found by importlib.
if early_config.known_args_namespace.pyargs:
invocation_dir_str = str(early_config.invocation_params.dir)
if invocation_dir_str not in sys.path:
sys.path.insert(0, invocation_dir_str)

args, _args_source = early_config._decide_args(
args=early_config.known_args_namespace.file_or_dir,
pyargs=early_config.known_args_namespace.pyargs,
Expand Down
21 changes: 21 additions & 0 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,27 @@ def test_pyargs_filename_looks_like_module(self, pytester: Pytester) -> None:
result = pytester.runpytest("--pyargs", "t.py")
assert result.ret == ExitCode.OK

def test_pyargs_finds_module_in_current_dir(self, pytester: Pytester) -> None:
"""Regression test for issue #14048.

Test that --pyargs can find modules in the current directory
(invocation directory) even when pytest's rootdir is different.
This is important for tox usage where pytest is run from a subdirectory.
"""
# Create a module structure in the current directory
pkg = pytester.mkpydir("amodule")
tests_pkg = pkg / "tests"
tests_pkg.mkdir()
tests_pkg.joinpath("__init__.py").write_text("", encoding="utf-8")
tests_pkg.joinpath("test_some.py").write_text(
"def test_something():\n assert True", encoding="utf-8"
)

# Run pytest with --pyargs from the directory containing the module
result = pytester.runpytest("--pyargs", "amodule.tests")
assert result.ret == ExitCode.OK
result.stdout.fnmatch_lines(["*1 passed*"])

def test_cmdline_python_package(self, pytester: Pytester, monkeypatch) -> None:
import warnings

Expand Down