Skip to content

Config-driven autodoc packages via wheel path#17

Merged
chrizzFTD merged 4 commits into
cursor/autodoc-bootstrap-src-only-16b5from
cursor/autodoc-packages-config-c412
Jul 2, 2026
Merged

Config-driven autodoc packages via wheel path#17
chrizzFTD merged 4 commits into
cursor/autodoc-bootstrap-src-only-16b5from
cursor/autodoc-packages-config-c412

Conversation

@chrizzFTD

Copy link
Copy Markdown
Owner

Summary

Stacks on #16. Replaces autodoc module introspection and silent :src: bootstrap with a single config knob, pyrepl_autodoc_packages.

  • Remove pyrepl_autodoc_bootstrap and _resolve_autodoc_bootstrap (importlib / inspect gone)
  • Add pyrepl_autodoc_packages — when set, every autodoc doctest REPL gets packages= from config; when unset, replay only
  • Move autodoc demo into pyrepl_test_pkg (demo.example_generator); rebuild committed wheel fixture
  • Add scripts/build_test_pkg_wheel.py to rebuild/copy the fixture wheel
  • Option B: add pyrepl_test_pkg @ file:./tests/fixtures/pyrepl_test_pkg to [docs] extra for one-command pip install -e ".[docs]" (local + RTD)
  • Update docs, README, and tests

Behavior

pyrepl_autodoc_packages Autodoc REPL
unset / None / "" Replay only
wheel path or PyPI name Replay + packages= from config

Autodoc assumes a single documented package. Host build still imports it normally; the browser REPL preloads via the configured wheel.

Test plan

  • pytest — 26 passed
  • Manual: confirm autodoc REPL on docs example page loads pyrepl_test_pkg from wheel after deploy
Open in Web Open in Cursor 

Replace module introspection and silent :src: bootstrap for autodoc REPLs
with a single pyrepl_autodoc_packages config value. Remove
pyrepl_autodoc_bootstrap.

Move the autodoc doctest example into pyrepl_test_pkg, rebuild the committed
wheel fixture, and add scripts/build_test_pkg_wheel.py. Wire the fixture into
the [docs] optional extra for one-command local and RTD doc builds.

Update docs, README, and tests to match the wheel-based autodoc workflow.

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

read-the-docs-community Bot commented Jul 1, 2026

Copy link
Copy Markdown

Documentation build overview

📚 sphinx-pyrepl-web | 🛠️ Build #33401240 | 📁 Comparing c6dcd98 against latest (931ed8b)

  🔍 Preview build  

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

@chrizzFTD

Copy link
Copy Markdown
Owner Author

@cursoragent review

@cursor

cursor Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Review: #17 — Config-driven autodoc packages via wheel path

Verdict: Approve. This delivers the planned simplification cleanly and stacks well on #16. RTD preview build succeeded.


What works well

Architecture. Replacing ~45 lines of module introspection with a 3-line config lookup is the right trade-off. One mechanism (wheel/packages=) for both manual .. py-repl:: and autodoc — no more :src: copying or PyPI-name guessing.

Config design. Collapsing pyrepl_autodoc_bootstrap into pyrepl_autodoc_packages is self-documenting:

def _autodoc_packages(app: Sphinx) -> str | None:
    """Return configured package preload for autodoc doctest REPLs."""
    return app.config.pyrepl_autodoc_packages or None

Unset → replay only. Set → preload. No ambiguous half-states.

Option B. The [docs] extra wiring is correct and keeps RTD unchanged:

docs = [
    "myst-parser",
    "pyrepl_test_pkg @ file:./tests/fixtures/pyrepl_test_pkg",
]

Tests. Good coverage of the three behaviors that matter: packages emitted, packages regardless of module location, replay-only when unset. The pyrepl_tag extraction avoids false positives from <script src=...>.

Tooling. scripts/build_test_pkg_wheel.py is practical — handles pip emitting py2.py3-none-any while normalizing to the committed filename.

Docs narrative. Autodoc and local-wheel examples now tell one coherent story via pyrepl_test_pkg.


Issues / nits

1. Dead code: register_startup_file (minor, optional cleanup)

register_startup_file is defined but no longer called anywhere after this PR. The PyRepl directive duplicates startup-file tracking inline. Safe to remove register_startup_file in this PR or a quick follow-up — it's the only leftover from the old bootstrap path.

2. make_pyrepl_raw still accepts src (nit)

Autodoc never passes src anymore. The parameter is harmless but could be dropped from the autodoc helper signature to avoid implying :src: bootstrap still exists. Not blocking.

3. literalinclude crosses repo boundaries (nit)

.. literalinclude:: ../../tests/fixtures/pyrepl_test_pkg/pyrepl_test_pkg/demo.py
   :language: python

RTD build passed, so it works. It's slightly unusual for published docs to reference tests/fixtures/. Alternatives: show the source only via the live autofunction output, or add a one-line note that the path is repo-internal. Fine as-is for a maintainer-facing example site.

4. Breaking change: document on merge to main

pyrepl_autodoc_bootstrap is removed with no deprecation shim. Appropriate for pre-1.0, but worth a line in the merge commit / release notes when #16+#17 land on main.

5. [docs] extra from PyPI (known limitation, documented)

pip install sphinx-pyrepl-web[docs] from PyPI will fail on the path dependency. README already frames [docs] as clone-only — good. No action needed.

6. No Sphinx warning when packages config points to a missing wheel (acceptable)

Same as the manual :packages: directive — user responsibility to set html_static_path and place the wheel. Consistent; no change needed unless you want proactive diagnostics later.


Test gap (non-blocking)

No test for comma-separated pyrepl_autodoc_packages (e.g. "numpy, _static/wheels/foo.whl"). Low risk since it reuses the same string passthrough as the directive (already tested in test_local_wheel.py). Could add a one-liner unit test on _autodoc_packages if you want symmetry.


Merge checklist

Step Status
#16 merged first prerequisite
pytest (26 passed) done
RTD preview (#17) passed
Manual: autodoc REPL loads pyrepl_test_pkg from wheel still open

Summary

The PR achieves the design goals: minimal extension code, no introspection debt, single config knob, fixture consolidated under pyrepl_test_pkg, Option B for doc builds. I'd merge after #16 with at most a quick dead-code cleanup for register_startup_file.

Want me to push a small follow-up commit removing register_startup_file before merge?

Open in Web Open in Cursor 

chrizzFTD and others added 3 commits July 2, 2026 07:59
When pyrepl_autodoc_packages is set, generate a silent bootstrap script
that imports the documented object from autodoc desc_signature metadata
before replaying doctest input. This lets unqualified doctest names like
example_generator work without changing docstrings.

Bootstrap scripts are written alongside replay files under
_static/pyrepl/ and emitted as src= on autodoc py-repl widgets.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
Co-authored-by: chrizzftd <chrizzFTD@users.noreply.github.com>
PR #18 merged auto-import bootstrap that emits silent src= bootstrap
scripts alongside packages=. The prior cleanup commit removed the src
parameter from make_pyrepl_raw, causing TypeError in transform_doctest_blocks
and failing CI/RTD builds.

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

Copy link
Copy Markdown
Owner Author

@cursoragent review

@cursor

cursor Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Review: #17 (current state) — Config-driven autodoc packages via wheel path

Verdict: Approve. CI/RTD are green again. The branch now delivers both #17 (wheel preload) and #18 (auto-import bootstrap) as a coherent autodoc story.


What changed since the first review

The branch picked up #18 after the initial review, then a cleanup commit briefly broke builds by removing src from make_pyrepl_raw. That's fixed in c6dcd98.

Current autodoc REPL behavior (when pyrepl_autodoc_packages is set):

Layer Mechanism
Package install packages= from pyrepl_autodoc_packages
Name binding Silent src= bootstrap script (from module import name) generated from autodoc metadata
Doctest replay replay-src= with original doctest input

Unset pyrepl_autodoc_packages → replay only, no wheel install, no auto-import. Clean single-knob design.


What works well

Architecture. The old introspection path is gone. Replacement is two small, explicit mechanisms:

  • config-driven wheel path (_autodoc_packages)
  • metadata-driven import script (autodoc_bootstrap_source + register_autodoc_bootstrap)

No copying source files from arbitrary module locations.

#17 + #18 fit together. Bootstrap imports only run when packages is set — imports without an installed package would be pointless. Good coupling.

Bootstrap source logic is simple and testable:

def autodoc_bootstrap_source(
    module: str | None,
    fullname: str | None,
    objtype: str | None,
) -> str | None:
    ...
    if "." in fullname:
        root = fullname.split(".", 1)[0]
        return f"from {module} import {root}\n"

Methods get their enclosing class imported, which is the right default for unqualified doctest names like example_generator(4).

Tests. 31 passed (up from 26). Coverage spans packages emission, out-of-tree modules, replay-only fallback, bootstrap script content, and autodoc_bootstrap_source unit cases.

Infra. RTD preview build succeeded on c6dcd98. Option B [docs] extra works. Wheel build script is in place.

Docs/README already describe the combined behavior (wheel + auto-import).


Issues / nits

1. PR description is stale (update before merge)

The PR body still describes #17 only — no mention of #18's auto-import bootstrap or the src= scripts under _static/pyrepl/. The behavior table should be:

pyrepl_autodoc_packages Autodoc REPL
unset Replay only
set packages= + silent import bootstrap + replay

Worth updating the description so reviewers and future readers aren't confused.

2. literalinclude from tests/fixtures/ (minor)

Still crosses repo boundaries in example.rst. Works on RTD; slightly unusual for published docs. Fine for a maintainer-facing example site.

3. Breaking API change (document on merge to main)

pyrepl_autodoc_bootstrap removed with no shim. Appropriate pre-1.0; note in release/merge notes when #16+#17 land.

4. [docs] extra not installable from PyPI (known, documented)

Path dependency in pyproject.toml — clone-only. Already documented in README.

5. Minor: triple _find_autodoc_desc call per node (nit)

Lines 152, 159, and implicitly via _inside_autodoc_desc — could cache desc once. Not worth blocking.


Resolved since first review

Item Status
Dead register_startup_file Removed ✓
make_pyrepl_raw src param Correctly kept for #18 bootstrap ✓
CI/RTD failures Fixed (c6dcd98) ✓

Merge checklist

Step Status
#16 merged first prerequisite
pytest (31 passed)
RTD preview ✓ (build #33401240)
PR description updated recommended
Manual: autodoc REPL loads package + runs doctest still open

Summary

The branch is in good shape to merge after #16. The design is cleaner than the original introspection approach, and #18's auto-import layer makes the wheel-based model actually usable with standard unqualified doctest examples.

Recommended before merge: update the PR description to reflect the combined #17+#18 behavior. Everything else is non-blocking.

Open in Web Open in Cursor 

@chrizzFTD chrizzFTD marked this pull request as ready for review July 2, 2026 09:55
@chrizzFTD chrizzFTD merged commit b773213 into cursor/autodoc-bootstrap-src-only-16b5 Jul 2, 2026
4 checks passed
@chrizzFTD chrizzFTD deleted the cursor/autodoc-packages-config-c412 branch July 2, 2026 10:28
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