Implement the typed doctest core architecture - #93
Conversation
why: Test the ADR boundaries against stock prompt semantics, typed markup extraction, shared groups, and extended execution. what: - Add immutable contracts, settings, models, and registry snapshots - Extract and project reStructuredText and MyST into group recipes - Run prompt and exec lanes with typed results and cleanup policy - Cover projection, runtime, registry, and Sphinx doctree behavior
why: Keep the released direct API and command shape while exercising the same extraction, projection, and execution path as other hosts. what: - Adapt the finder and direct runner to typed block and group results - Preserve stock failure and summary accounting across Python versions - Add direct facade ordering, location, and reporting regressions
why: Preserve pytest fixtures, checker semantics, and reporting without blocking the built-in doctest plugin or splitting shared group state. what: - Add one item per group with fresh attempt-local doctest materialization - Quarantine private pytest compatibility and filter duplicate collectors - Exercise fixtures, reruns, xdist, async fixtures, and contributions - Package the typed core, adapters, tests, and corrected plugin entry point
why: Broad major-version constraints hid invalid dependency combinations and did not prove the declared Python and pytest floor. what: - Pin docutils, pytest, asyncio, and rerun plugin matrix versions - Select the matrix interpreter for every uv command - Check installed dependency consistency before static and runtime gates
why: The proposed architecture contained compatibility and lifecycle claims that changed when exercised against real hosts and version floors. what: - Record the typed-core and thin-adapter bakeoff result - Narrow vanilla, diagnostics, line, and pytest compatibility promises - Define runner and registry contracts proven by the implementation - List deferred host lifecycle, reporting, async, and facade work
why: Public guidance must distinguish the direct command from pytest's one-item-per-group behavior without promising full stdlib transcripts. what: - Describe direct doctest command and summary behavior - Explain built-in pytest doctest plugin composition - Clarify bare-block isolation and the Sphinx default directive group - State the supported docutils range
8b887ad to
36f1a1f
Compare
why: The rebase onto master dropped this branch's `docutils<0.22` cap, on the reasoning that master tests 0.22.4 successfully. That was wrong. Sphinx declares `docutils>=0.20,<0.22`, so 0.22.4 leaves the environment inconsistent, and this branch's `uv pip check` step fails on it. Master has no such step, which is why it never noticed. what: - Restore `docutils>=0.20.1,<0.22` - Return the matrix to docutils 0.20.1 and 0.21.2 - Drop the Python 3.10 exclusion, which only existed to keep 3.10 away from docutils 0.22 and cannot trigger under the ceiling Verified `uv pip check` clean and 227 tests passing on docutils 0.20.1 and 0.21.2 against pytest 8.4.2 and 9.1.1.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## adr-doctest-core-architecture #93 +/- ##
=================================================================
+ Coverage 76.68% 84.93% +8.25%
=================================================================
Files 15 26 +11
Lines 1025 2470 +1445
=================================================================
+ Hits 786 2098 +1312
- Misses 239 372 +133 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
7f041dc to
a47d332
Compare
|
Rebased onto current master. The stack is preserved: #92 carries the first 24 commits onto master, this PR the remaining 7 on top of it. Both are green. Why it needed rebasing. Master gained Conflicts, and how they were resolved. Three files; everything else applied clean.
One resolution I got wrong, and this branch caught. I initially dropped the State: mypy clean across 31 source files, ruff clean, 227 tests passing, Worth deciding: Pre-rebase tips are preserved locally at |
Depends on #92.
Summary
doctest_corepipeline for parsing, projection, registration, and execution.doctest_docutilsandpytest_doctest_docutilsas adapters over the core while preserving their command and collection surfaces.doctest.DocTestand source location for each block.docutils,pytest,pytest-asyncio, andpytest-rerunfailuresversions.The architecture ADR remains proposed. This draft implements it against the existing direct and pytest entry points so the contracts can be reviewed against executable behavior.
Why
The direct and pytest paths previously owned overlapping parsing and execution behavior. The pytest adapter also blocked the standard doctest plugin while depending on its implementation. A shared core separates host integration, scheduling identity, and diagnostic identity without merging source blocks or adding an xdist affinity protocol.
Impact
Documentation blocks within a group share one namespace, but each block retains its own location and failure detail. The pytest adapter coexists with the standard doctest plugin, so pytest continues to provide fixtures, checker and report options, and Python-module doctest collection.
Validation
uv run ruff format . --checkuv run py.testuv run ruff check .uv run mypy .just build-docsKnown CI failure
The push workflow fails in
mypyfor Python 3.13 withdocutils==0.21.2andpytest==7.2.0. An isolated local run with the same pins reproduces strict typing errors insrc/_pytest_doctest_compat.pyandsrc/pytest_doctest_docutils.py; the equivalentpytest==8.4.2run passes. The oldest pytest line exposes the private compatibility surface with weaker annotations, so the blocker remains unresolved.