feat(_ext[sphinx_pytest_fixtures]): Sphinx extension for pytest fixture documentation#656
Merged
feat(_ext[sphinx_pytest_fixtures]): Sphinx extension for pytest fixture documentation#656
Conversation
…_pytest_fixtures why: The new sphinx_pytest_fixtures extension uses docutils node types that need type stubs for mypy, and its integration tests use a custom pytest marker. what: - Add types-docutils to dev dependencies in pyproject.toml - Add mypy override to ignore missing imports for sphinx_pytest_fixtures and sphinx_pytest_fixtures.* (extension lives under docs/_ext, outside the mypy src/tests search path) - Register "integration" pytest marker for sphinx integration tests - Update uv.lock with types-docutils resolution
…patibility why: The new sphinx_pytest_fixtures extension auto-generates "Used by" and "Returns" fields from introspection, so hand-written duplicates cause double rendering. Cross-references also need :fixture: role instead of :func: to resolve against the new py:fixture domain object. what: - Change :func:`user_path` to :fixture:`user_path` in home_user_name docstring - Remove manual "Used by: :func:`config_file`, :func:`zshrc`" from user_path docstring (now auto-generated) - Remove redundant Returns section from TestServer docstring (return type is inferred from the annotation)
…ixture documentation why: pytest fixtures lack first-class Sphinx support — they render as plain functions with full call signatures, hiding scope, dependencies, and usage patterns. This extension treats fixtures as domain objects with badge-based metadata, auto-generated usage snippets, and cross-referenced dependency graphs. what: - __init__.py: extension setup, domain registration (py:fixture directive + :fixture: xref role), CSS self-registration - _badges.py: scope/kind/autouse/deprecated badge nodes with WCAG AA contrast in light and dark mode - _constants.py: field labels, config keys, table spec, regex, extension version, and store version constants - _css.py: CSS class name constants for badge/card/index styling - _detection.py: fixture introspection — marker extraction, scope detection, dependency classification, return type annotation, factory/async detection, TYPE_CHECKING forward-ref resolution - _directives.py: PyFixtureDirective (py:fixture), AutofixturesDirective (bulk module discovery), AutofixtureIndexDirective (index table) - _documenter.py: autodoc-style FixtureDocumenter for autofixture:: - _index.py: index table builder with linked return types via intersphinx, Flags column with scope/kind/autouse badges - _metadata.py: FixtureMeta extraction — docstring summary, teardown summary from Teardown docstring section, usage snippet generation, forward-ref qualification - _models.py: FixtureMeta and FixtureDep dataclasses, TypedDict for store entries, autofixture_index_node placeholder - _store.py: environment-safe fixture store with merge-info collision detection (SPF009), finalization, and builtin URL resolution - _transforms.py: doctree transforms — badge injection, field list augmentation, dependency rendering, callout insertion - _validation.py: stable warning codes SPF001–SPF006 with configurable lint_level (warn or error) - _static/css/sphinx_pytest_fixtures.css: 387 lines of responsive CSS for badge pills, fixture cards, index table, mobile stacking, dark-mode tokens, and focus-accessible tooltips
…page why: The badge demo page needs fixtures that exercise every badge permutation (scope × kind × state) without depending on libtmux's real fixtures, which only cover a subset of combinations. what: - Add spf_demo_fixtures.py with 9 synthetic @pytest.fixture functions covering: plain, session/module/class scope, factory kind, override_hook kind, autouse, deprecated, and two combinations (session+factory, session+autouse)
…ctree why: The extension must be listed in conf.py to activate, and the new demo/ section needs a toctree entry so Sphinx includes it in the build. what: - Add "sphinx_pytest_fixtures" to extensions list in docs/conf.py - Add demo/index to root toctree in docs/index.md
…irectives
why: The previous fixture reference used a single automodule dump that
rendered fixtures as plain functions. The new page uses autofixture
directives to show fixtures grouped by purpose (core, environment,
override hooks, factories) with a decision guide and configuration
reference.
what:
- Rewrite docs/api/testing/pytest-plugin/fixtures.md with Quick Start
section, "Which Fixture Do I Need?" guide, autofixture-index table,
grouped autofixture directives with inline examples, and confval
configuration reference
- Update docs/api/testing/pytest-plugin/usage.md to change {func} xrefs
to {fixture} xrefs (home_path, user_path, config_file, session,
server, session_params, TestServer) to match the new domain objects
why: Badge rendering varies across themes, zoom levels, and light/dark modes. A dedicated demo page provides a visual reference for all badge permutations to verify rendering correctness during development. what: - Add docs/demo/index.md as demo hub with description and toctree - Add docs/demo/sphinx-pytest-fixtures-badges.md with sections for every badge permutation: plain, scope (session/module/class), kind (factory/override_hook), state (autouse/deprecated), and combinations (session+factory, session+autouse)
…odules why: Each extension submodule (_detection, _metadata, _store, _badges, _directives, _validation, _index) has branching logic and edge cases that must be tested in isolation without requiring full Sphinx builds. what: - 1,385 lines of pytest tests covering: - _is_pytest_fixture positive/negative detection - _get_user_deps filtering of hidden and builtin fixtures - _classify_deps partitioning into internal, builtin, external - _get_return_annotation with typing generics and forward refs - _is_factory heuristic for type[X] and Callable returns - _build_usage_snippet for resource, factory, override_hook kinds - _build_badge_group_node for scope/kind/autouse/deprecated badges - _qualify_forward_ref with TYPE_CHECKING block resolution - _extract_summary sentence boundary and EOF handling - _extract_teardown_summary from Teardown docstring sections - SPF001–SPF009 validation warnings and error-level lint - FixtureMeta.param_reprs wiring from :params: directive option - Store env_version guard and docname collision detection - CSS class contract tests and tabindex accessibility - Index table Flags column badge rendering
why: Unit tests verify individual functions but cannot catch issues in the full Sphinx rendering pipeline — directive registration, doctree transforms, cross-reference resolution, intersphinx link generation, and CSS inclusion all require end-to-end Sphinx builds. what: - 1,853 lines of pytest integration tests (marked @pytest.mark.integration) using Sphinx's make_app test helper, covering: - AutofixturesDirective bulk discovery and source-order rendering - AutofixtureIndexDirective table structure and linked return types - PyFixtureDirective with :scope:, :kind:, :deprecated: options - :fixture: cross-reference resolution with short-name fallback - Badge rendering for all scope/kind/state permutations - Parametrized values as inline and enumerated lists - Teardown summary injection into yield-fixture callouts - "Used by" cross-document link generation - External URL rendering for dependency links - :usage: none suppression of auto-generated snippets - Excluded fixtures absent from index table - Scope/kind pair-index entry structure - SPF003 warning for yield fixtures via autodoc - Async fixture callout rendering - Text builder compatibility (no crash on non-HTML)
c6d70a8 to
cd0fa92
Compare
why: Document the new extension, bug fix, and dev dependency for the upcoming release notes. what: - Add "What's new" entry for sphinx_pytest_fixtures extension listing directives, roles, badges, responsive layout, WCAG compliance, and test count - Add "Bug fixes" entry for session_params docstring fix - Add "Development" entry for types-docutils dev dependency
…ppercase without colon
why: Bold field labels ("Depends on:", "Used by:") competed visually
with fixture names and section headings. The colon is redundant in a
grid layout where spatial alignment already signals key-value pairs.
what:
- Set font-weight: normal on fixture field-list dt elements
- Add text-transform: uppercase with 0.85em font-size and slight
letter-spacing for a metadata-label treatment
- Hide the Sphinx-injected .colon span via display: none
cd0fa92 to
4a0dc69
Compare
11f5abf to
4a0dc69
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docs/_ext/sphinx_pytest_fixtures/) that renders pytest fixtures as first-class API documentation with scope/kind/factory badges, cross-referenced dependencies, and auto-generated usage snippets.. autofixture::directive — autodoc-style documenter for individual fixtures.. autofixtures::directive — bulk discovery and rendering from a module.. autofixture-index::directive — auto-generated summary table with linked return types (via intersphinx) and parsed RST descriptions:fixture:cross-reference role with short-name resolutionpytest_plugin.pydocstrings: remove duplicate hand-written fields now auto-generated by the extension, update:func:→:fixture:xrefsTest plan
uv run pytest tests/docs/_ext/test_sphinx_pytest_fixtures.py— 70+ unit tests for detection, metadata, store, badges, validation, indexuv run pytest tests/docs/_ext/test_sphinx_pytest_fixtures_integration.py— 39+ integration tests requiring full Sphinx buildsuv run ruff check .— no lint violationsuv run mypy src tests— type checking passesuv run sphinx-build -b html docs docs/_build/html— docs build without errors/api/testing/pytest-plugin/fixtures//demo/sphinx-pytest-fixtures-badges/