Skip to content

Add autodoc doctest_block REPL integration#12

Merged
chrizzFTD merged 14 commits into
mainfrom
cursor/autodoc-doctest-repl-3c18
Jun 29, 2026
Merged

Add autodoc doctest_block REPL integration#12
chrizzFTD merged 14 commits into
mainfrom
cursor/autodoc-doctest-repl-3c18

Conversation

@chrizzFTD

@chrizzFTD chrizzFTD commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • Transform autodoc doctest_block nodes into interactive widgets via a doctree-read hook
  • Extract replay input with doctest.DocTestParser
  • Opt-in via pyrepl_doctest_blocks
  • Log bootstrap failures at error level

Testing

pytest -v

All 21 tests pass, including new autodoc integration and scope tests.

Open in Web Open in Cursor 

Transform doctest blocks inside autodoc API entries into interactive
py-repl widgets using stdlib doctest.DocTestParser for source extraction.

- Add pyrepl_doctest_blocks config (default: autodoc)
- Refactor register_replay_script() shared by directive and transform
- Remove unused :strip-prompts: option
- Add tests and docs with example_generator demo

Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
@read-the-docs-community

read-the-docs-community Bot commented Jun 27, 2026

Copy link
Copy Markdown

Documentation build overview

📚 sphinx-pyrepl-web | 🛠️ Build #33353114 | 📁 Comparing 4b639f6 against latest (ef2ee2b)

  🔍 Preview build  

3 files changed
± example.html
± genindex.html
± index.html

cursoragent and others added 3 commits June 27, 2026 22:30
Move doctest_block transform from doctree-resolved to doctree-read.
env-updated (which writes replay scripts) runs after read but before
write, so metadata registered during doctree-resolved was too late.

Add regression test for include:: pattern used on RTD docs.

Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
Load the documented module's source before replaying doctest examples,
using the existing src + replay-src pattern from pyrepl-web.

- Modules under srcdir: reuse the source file via :src:
- Modules elsewhere: generate a bootstrap script in _static/pyrepl/
- Prefer sys.modules (already imported by autodoc) over re-import
- Add pyrepl_autodoc_bootstrap config (default: True)

Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
CI sets PYTHONWARNINGS=error; Napoleon triggers
RemovedInSphinx11Warning during autodoc integration tests.
Filter this upstream deprecation until Napoleon is updated.

Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
@chrizzFTD

Copy link
Copy Markdown
Owner Author

@cursoragent review

@cursor

cursor Bot commented Jun 27, 2026

Copy link
Copy Markdown

PR Review: Add autodoc doctest_block REPL integration (#12)

Verdict: Approve with one fix recommended before merge

This is a solid, low-maintenance integration. It reuses existing machinery well, tests are thorough, and the RTD preview confirms the happy path works. One functional bug should be addressed; the rest are minor polish items.


What works well

Architecture — Transforming doctest_block nodes on doctree-read (not doctree-resolved) is the right call. The earlier bug (replay scripts registered too late for env-updated) was correctly diagnosed and fixed.

Source extraction — Using doctest.DocTestParser instead of strip_doctest_prompts for autodoc blocks is correct; expected output lines are properly stripped.

Bootstrap — Reusing the existing silent :src: + replay-src pattern is elegant and consistent with the setup.py example. Preferring sys.modules over re-import avoids the test pollution issue we hit.

Tests — Good coverage: unit tests for extraction, integration for scope modes, include-pattern regression, bootstrap paths (srcdir vs generated), and on-disk file assertions. 21 tests, 96% coverage, CI command passes locally.

Docs — README and live RTD example with example_generator are clear and accurate.


Bug: JS not loaded on autodoc-only pages

doctree_read and transform_doctest_blocks both hook doctree-read, but run in registration order:

  1. doctree_read — checks env.metadata["pyrepl"] (not set yet for autodoc-only pages)
  2. transform_doctest_blocks — sets metadata and replaces nodes

So on a page with only .. autofunction:: (no manual .. py-repl::), the <py-repl> element is emitted but pyrepl.js is never included.

Verified locally: metadata has pyrepl=True, but doctree["pyrepl"] is missing and there is no script tag in the HTML.

This does not affect the docs site because index.rst also includes manual .. py-repl:: directives, which set the flag during parsing. Pure API reference pages would break silently.

Suggested fix — in transform_doctest_blocks, also mark the doctree:

if replaced:
    env.metadata[docname]["pyrepl"] = True
    doctree["pyrepl"] = True

Or swap handler order / merge the two doctree-read handlers.


Minor issues

Item Notes
Stale PR description Says doctree-resolved hook and "19 tests"; implementation uses doctree-read, 21 tests. Worth updating before merge.
Bootstrap scope Loads the entire module via inspect.getsource(mod_obj). Fine for demo modules; could be slow or fail for large modules with heavy imports. Acceptable for v1; worth documenting.
Silent bootstrap failures C extensions, builtins, or import errors fall back to replay-only with no warning. Users see NameError at runtime. Consider a Sphinx logger.warning on bootstrap failure.
Version Still 0.1.1 despite a significant feature. Consider bumping to 0.2.0.
Import order import sys after pathlib in __init__.py — minor style nit.

Out of scope (fine for v1)

  • Napoleon code-block Examples (non->>> format)
  • Pyodide-incompatible imports in bootstrapped modules
  • Per-member opt-out (e.g. :no-pyrepl: autodoc option)

Summary

Area Rating
Design Strong — minimal new surface, reuses existing pipeline
Correctness Good, except autodoc-only JS loading
Tests Strong
Docs Good
CI Fixed (Napoleon deprecation filter)

Recommendation: Fix the doctree["pyrepl"] flag issue, then merge. Everything else can follow up in a patch release if you prefer to ship now.

Open in Web Open in Cursor 

transform_doctest_blocks runs after doctree_read on the same event,
so autodoc-only pages never got doctree["pyrepl"] set and pyrepl.js
was omitted from HTML output.

Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
@chrizzFTD
chrizzFTD marked this pull request as ready for review June 28, 2026 00:21
chrizzFTD and others added 6 commits June 28, 2026 10:22
Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
chrizzFTD and others added 2 commits June 28, 2026 19:33
Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
)

* Unify doctest replay extraction and fix installed-package bootstrap

Add doctest_to_replay_source() as the single conversion path for both
autodoc doctest blocks and py-repl directive bodies. DocTestParser strips
expected output and joins separate examples with blank lines so multiline
class definitions remain valid Python.

For installed modules outside the Sphinx source tree, autodoc REPLs now
emit packages= via micropip instead of exec'ing module source (which fails
for packages with relative imports). In-tree modules still use silent :src:.

---------

Signed-off-by: Christian López Barrón <chris.gfz@gmail.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
@chrizzFTD

Copy link
Copy Markdown
Owner Author

@cursoragent review

@cursor

cursor Bot commented Jun 29, 2026

Copy link
Copy Markdown

PR Review: Add autodoc doctest_block REPL integration (#12)

Verdict: Ready to merge

Since the first review, the blocking issues have been addressed. The PR is in good shape for merge.


Resolved since first review

Issue Status
Replay scripts not written (doctree-resolved vs env-updated) Fixed — uses doctree-read
NameError in autodoc REPLs Fixed — silent :src: bootstrap via pyrepl_autodoc_bootstrap
JS missing on autodoc-only pages Fixed — doctree["pyrepl"] = True in transform
CI failures (PYTHONWARNINGS=error + Napoleon) Fixed — pytest filter in pyproject.toml
Version bump Done — 0.2.0
README verbosity Improved — config tables for both options
Docs / RTD preview Working per RTD bot

What still works well

  • Designdoctest_block transform + DocTestParser + existing replay/copy_asset_files pipeline is minimal and maintainable.
  • Bootstrap — Reuses the established :src: + replay-src pattern; srcdir files vs generated bootstrap is a sensible split.
  • Tests — 21 tests, scope modes, include pattern, bootstrap paths, on-disk assertions; CI command passes locally.
  • Docs — README is concise; RTD live demo validates the feature.

Remaining nits (non-blocking)

  1. Stale PR description — Still says doctree-resolved, "19 tests", and omits bootstrap/pyrepl_autodoc_bootstrap. Worth updating before or right after merge so GitHub history matches reality.

  2. Silent bootstrap failures_resolve_autodoc_bootstrap swallows errors and falls back to replay-only; users may still see NameError with no build warning. Fine for v1; a logger.warning would help debugging later.

  3. Full-module bootstrap — Loads entire module source, not just the documented member. Documented and acceptable for v1.

  4. import sys placement — Minor style: sys import after pathlib in __init__.py.

  5. README grammar — Line 76: "this integrates""which integrates" or split into two sentences (cosmetic).


Summary

Area Rating
Design Strong
Correctness Good — known edge cases documented
Tests Strong
Docs Good
CI / RTD Green

Recommendation: Merge. Optional follow-up: refresh the PR description to reflect doctree-read, 21 tests, bootstrap config, and version 0.2.0.

Open in Web Open in Cursor 

- logger.error when autodoc REPL bootstrap cannot resolve module source
- Fix docstring conversion sentence in README
- Add test for bootstrap failure logging

Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
@chrizzFTD
chrizzFTD merged commit 931ed8b into main Jun 29, 2026
4 checks passed
@chrizzFTD
chrizzFTD deleted the cursor/autodoc-doctest-repl-3c18 branch June 29, 2026 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants