pytest public API boundary ambiguity causes silent plugin breakage on minor upgrades
0 reputation · 12 Aug 2020, 05:06 UTC
0 reputation · 12 Aug 2020, 05:06 UTC
Identify which pytest symbols are safe for plugins and test code to import without risk of breaking changes across minor versions.
pytest re-exports internal symbols like FixtureRequest, Parser, and HookspecMarker at the top level without provisional markers. The official API reference documents only a subset as stable. No py.typed markers exist for static analysis, and no pytest --check-public-api tool warns about internal imports. Documentation often lags behind internal refactors, so the online reference may list moved or removed symbols.
pluggy's hookspecs to stabilize the contract?There is no machine-readable manifest or versioned contract that definitively distinguishes pytest's guaranteed-public symbols from internal re-exports. The project relies on informal stability: symbols documented in the official reference are treated as stable, while undocumented or changelog-noted re-exports may break without notice across minor versions.
pytest.__all__ contains the current public surface, but this list evolves without semantic versioning guarantees for individual symbols.FixtureRequest, Parser, and HookspecMarker are re-exported at the top level but are not marked as provisional or stable in documentation.py.typed marker exists in the package, but type hints do not indicate stability levels (e.g., no @deprecated or @provisional decorators).pytest root unless the symbol is explicitly documented.requirements.txt or pyproject.toml and subscribe to changelog notifications. The pytest changelog explicitly notes when symbols are removed or moved._pytest.fixtures) with awareness that these are internal APIs with no stability guarantee.Adopting a pluggy-style hookspec layer for the public API would require deliberate project-level changes. Such a layer would need:
FutureWarning or DeprecationWarning before removal.This does not exist in pytest today. Any plugin seeking long-term stability should minimize reliance on top-level re-exports and monitor the changelog closely.
python -c "import pytest; print([x for x in dir(pytest) if not x.startswith('_')])" to list all public names.pytest/__init__.pyi (if present) or pytest/__init__.py for __all__ definition.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.