3.2 KiB
Pytest source notes
Repo: pytest-dev/pytest
Local checkout: /home/ubuntu/repos/rodin-sources/pytest
Why this repo is useful
- Pytest is a strong source for package-facade patterns and lifecycle-heavy test helper patterns.
- It is especially useful because the public package is deliberately small compared to the internal
_pytest.*implementation tree.
The public package is a curated facade over internal modules
Repeated evidence
src/pytest/__init__.py:6-92re-exports the supported testing API from many_pytest.*implementation modules.src/pytest/__init__.py:98-186defines__all__explicitly, turning the package root into a maintained public surface.src/pytest/__init__.py:23-30includes compatibility-minded exports likeyield_fixture, showing that the facade also absorbs historical API pressure.
Why it matters
Repeated signal: large libraries can keep internal structure fluid while giving users one stable import surface. The top-level package behaves like an API contract, not just a mirror of file layout.
Caveat / counterexample
This pattern does create maintenance pressure: once the facade exports a name, deprecating or removing it becomes a public compatibility event. Pytest accepts that tradeoff intentionally.
Fixture cleanup is modeled as an explicit lifetime boundary
Repeated evidence
testing/test_monkeypatch.py:17-23defines a fixture that snapshots global state,yields the resource, then restores state after the test.testing/test_threadexception.py:84-90uses ayieldfixture where the teardown action intentionally runs after test execution.doc/en/how-to/fixtures.rst:551-553marksyieldfixtures as the recommended path.doc/en/how-to/fixtures.rst:669-677contrasts them withaddfinalizer, explicitly framing finalizers as the alternative when needed.
Why it matters
Repeated signal: pytest prefers resource lifetime that is legible in source order: setup before yield, teardown after yield. That shape scales better than hidden cleanup hooks.
Caveat / counterexample
request.addfinalizer(...) still exists for cases where teardown must be registered dynamically, but pytest's own docs present it as the less straightforward option. That is important evidence that yield fixtures are the convention, not just one possible style.
Failure expectations are explicit context boundaries
Repeated evidence
testing/test_monkeypatch.py:31-32,testing/test_monkeypatch.py:50-51, andtesting/test_monkeypatch.py:76-85repeatedly usewith pytest.raises(...)around the exact failing operation.testing/acceptance_test.py:513-514andtesting/test_pluginmanager.py:254-255show the same shape in broader integration tests.
Why it matters
Repeated signal: pytest encourages failure expectations that wrap the smallest relevant operation, keeping the expected failure boundary local and visible.
Pattern candidates supported by this repo
- expose a stable top-level facade over private implementation packages
- use explicit
__all__/re-export curation for public APIs - model test resource lifetime with
yieldfixtures - express expected failures with tight context-manager boundaries