Summary
With pytest-isolated installed, pytest --collect-only runs tests instead of only collecting them. This is not limited to @pytest.mark.isolated tests: the mere presence of the active plugin breaks collect-only for the entire session, including unmarked tests. Disabling the plugin (-p no:isolated) restores correct behavior.
Environment
- pytest-isolated: 0.4.3
- pytest: 9.0.2
- Python: 3.11 / 3.12 (reproduced on 3.12.3; root cause is version-independent)
- OS: Linux
Reproducer
test_repro.py:
import pathlib, pytest
def test_plain(): # NOT marked isolated
pathlib.Path("plain.ran").write_text("x")
assert True
@pytest.mark.isolated
def test_isolated():
pathlib.Path("isolated.ran").write_text("x")
assert True
Behavior matrix (file markers prove execution)
| command |
plain.ran |
isolated.ran |
pytest --collect-only |
YES |
YES |
pytest --collect-only --no-isolation |
YES |
YES |
pytest --co -q |
YES |
YES |
pytest -p no:isolated --collect-only |
no |
no |
A file containing zero isolated markers also runs its tests under --collect-only as long as the plugin is active, confirming the trigger is the plugin, not the marker.
Expected
--collect-only lists items and executes nothing (matching stock pytest, i.e. -p no:isolated).
Root cause (assumption ... please verify)
pytest_isolated/execution.py::pytest_runtestloop replaces pytest's built-in loop but omits the collect-only short-circuit. Stock _pytest.main.pytest_runtestloop early-returns when session.config.option.collectonly is set; the replacement only guards against the subprocess env var:
def pytest_runtestloop(session):
if os.environ.get(SUBPROC_ENV) == "1":
return None
# <-- no `if session.config.option.collectonly: return True` guard
... # proceeds to execute groups + remaining items
Suggested fix
Add the standard guard at the top of the custom loop:
if session.config.option.collectonly:
return True
(Mirrors _pytest.main.pytest_runtestloop. Returning True marks the hook as
handled and skips execution.)
Workaround
pytest -p no:isolated --collect-only until fixed.
Summary
With pytest-isolated installed,
pytest --collect-onlyruns tests instead of only collecting them. This is not limited to@pytest.mark.isolatedtests: the mere presence of the active plugin breaks collect-only for the entire session, including unmarked tests. Disabling the plugin (-p no:isolated) restores correct behavior.Environment
Reproducer
test_repro.py:Behavior matrix (file markers prove execution)
pytest --collect-onlypytest --collect-only --no-isolationpytest --co -qpytest -p no:isolated --collect-onlyA file containing zero isolated markers also runs its tests under
--collect-onlyas long as the plugin is active, confirming the trigger is the plugin, not the marker.Expected
--collect-onlylists items and executes nothing (matching stock pytest, i.e.-p no:isolated).Root cause (assumption ... please verify)
pytest_isolated/execution.py::pytest_runtestloopreplaces pytest's built-in loop but omits the collect-only short-circuit. Stock_pytest.main.pytest_runtestloopearly-returns whensession.config.option.collectonlyis set; the replacement only guards against the subprocess env var:Suggested fix
Add the standard guard at the top of the custom loop:
(Mirrors
_pytest.main.pytest_runtestloop. ReturningTruemarks the hook ashandled and skips execution.)
Workaround
pytest -p no:isolated --collect-onlyuntil fixed.