Summary
Two pytest infrastructure traps that hit every multi-module project:
-
tests/__init__.py files cause pytest plugin-name collisions under --import-mode=importlib. When the workspace root pyproject sets addopts = "--import-mode=importlib", having modules/<m>/tests/__init__.py files in two modules makes pytest try to register tests.conftest as a plugin twice — collision error. The fix is to not create tests/__init__.py; pytest discovers test files via path walk under importlib mode.
-
pytest_plugins = [...] in non-top-level conftest is forbidden by pytest 7.x. The framework's bundled host_conftest.py is meant to be loaded as a plugin, but if a module's conftest tries to register it via pytest_plugins, pytest raises:
pytest_plugins variable is not allowed in non-rootdir conftest.py files
Fix: register at the workspace-root conftest.py (one level above all modules) with pytest_plugins = ["host_conftest"]. Module conftests then inherit the plugin.
Reproduction
# Trap 1
echo > modules/lacowiki_legends/tests/__init__.py
echo > modules/lacowiki_datasets/tests/__init__.py
uv run pytest modules
# → "tests.conftest" plugin registered twice / import collision
# Trap 2
# In modules/lacowiki_legends/tests/conftest.py:
pytest_plugins = ["host_conftest"]
uv run pytest
# → ERROR: pytest_plugins variable is not allowed in non-rootdir conftest.py files
Workarounds
- Don't create
tests/__init__.py. Test files import via path discovery.
- Workspace root has a single
conftest.py with pytest_plugins = ["host_conftest"]. Module conftests are named conftest.py (no __init__.py parent) and just declare local fixtures.
Suggested fix
Update the framework docs / sm new scaffold to:
- Not create
tests/__init__.py in any module template.
- Generate a workspace-root
conftest.py with pytest_plugins = ["host_conftest"] when scaffolding a uv-workspace project.
- Document the importlib-mode + plugin-registration pattern prominently.
Environment
pytest>=8.0, pytest-asyncio>=0.24, importlib mode
- Discovered Phases 2–5 of laco_wiki_python rewrite.
Summary
Two pytest infrastructure traps that hit every multi-module project:
tests/__init__.pyfiles cause pytest plugin-name collisions under--import-mode=importlib. When the workspace root pyproject setsaddopts = "--import-mode=importlib", havingmodules/<m>/tests/__init__.pyfiles in two modules makes pytest try to registertests.conftestas a plugin twice — collision error. The fix is to not createtests/__init__.py; pytest discovers test files via path walk under importlib mode.pytest_plugins = [...]in non-top-level conftest is forbidden by pytest 7.x. The framework's bundledhost_conftest.pyis meant to be loaded as a plugin, but if a module's conftest tries to register it viapytest_plugins, pytest raises:Fix: register at the workspace-root
conftest.py(one level above all modules) withpytest_plugins = ["host_conftest"]. Module conftests then inherit the plugin.Reproduction
Workarounds
tests/__init__.py. Test files import via path discovery.conftest.pywithpytest_plugins = ["host_conftest"]. Module conftests are namedconftest.py(no__init__.pyparent) and just declare local fixtures.Suggested fix
Update the framework docs /
sm newscaffold to:tests/__init__.pyin any module template.conftest.pywithpytest_plugins = ["host_conftest"]when scaffolding a uv-workspace project.Environment
pytest>=8.0,pytest-asyncio>=0.24, importlib mode