Skip to content

Documentation? #30

Description

@stevepiercy

Should this package have its own Sphinx documentation? It's become large enough that autodoc of its API—thanks to new docstrings—might be useful, and then you wouldn't have to update the README with usage. We could either host it separately at RTD or pull it in as a submodule.

Activity

  1. added
    documentationImprovements or additions to documentation
    questionFurther information is requested
    on Mar 27, 2025
  2. jensens commented on Jul 13, 2026

    @jensens
    SponsorMember

    I looked into this and built a throwaway Sphinx project against the real package to check the assumptions. Short version of what I found and what I propose.

    Two obstacles to "just run autodoc"

    1. pytest fixtures are not functions.

    >>> type(pytest_plone.fixtures.base.portal)
    <class '_pytest.fixtures.FixtureFunctionDefinition'>

    sphinx.ext.autodoc introspects live objects, so autofunction sees no function here and produces nothing useful.

    2. Our docstrings are Markdown. They contain ```python fences, but sphinx.ext.autodoc feeds docstrings to the reStructuredText parser. MyST-parser's own docs state that autodoc is not compatible with MyST docstrings.

    Resolution: sphinx-autodoc2

    sphinx-autodoc2 does static AST analysis rather than runtime introspection, which dissolves both problems: it reads the function as written in the source, so the decorator is irrelevant, and autodoc2_docstring_parser_regexes lets it parse docstrings as MyST.

    Verified working (build succeeded, 0 warnings, signatures with resolved annotations, examples as highlighted code blocks):

    extensions = ["myst_parser", "autodoc2", "sphinx_design", "sphinx_copybutton"]
    autodoc2_packages = [{"path": "../src/pytest_plone", "auto_mode": False}]
    autodoc2_render_plugin = "myst"
    autodoc2_docstring_parser_regexes = [(r".*", "myst")]
    myst_enable_extensions = ["colon_fence", "deflist", "attrs_inline", "fieldlist"]
    html_theme = "plone_sphinx_theme"

    Two gotchas that cost me time: autodoc2_packages[…]["path"] must be relative to conf.py, and fieldlist is required or reST field syntax (:param x:, used in fixtures_factory) renders as literal text.

    The docs build needs no Plone

    Because autodoc2 is static, it never imports the package. My spike environment had zero Plone/Zope packages installed — not even pytest — and still produced fully resolved signatures like portal(integration: plone.testing.layer.Layer) → PloneSite.

    So the docs job needs only Sphinx + theme + autodoc2. Seconds, not the ~3 minutes a Plone install costs. It also removes what would have been the strongest argument against Read the Docs ("RTD would have to install all of Plone" — it would not).

    Prerequisite: the docstrings were wrong

    If the docstrings become the single source of truth, every error in them gets published verbatim. So I audited them first. Four were genuinely broken — setup_tool was not even valid Python, get_fti asserted isinstance(fti, IDexterityFTI) (always False; zope interfaces need providedBy), get_vocabulary referenced an undefined name, and http_request's example requested pytest's builtin request fixture. A further 14 used self in top-level test functions, which fails with fixture 'self' not found on copy-paste.

    Fixed in #55, with a static guard (#54) so they cannot come back.

    Proposed shape

    Diataxis, all four quadrants, two levels deep:

    docs/
    ├── index.md
    ├── tutorials/first-test.md
    ├── how-to/          set-up-pytest-plone, test-addon-install,
    │                    speed-up-the-test-suite, test-a-rest-api,
    │                    develop-the-plugin
    ├── explanation/     why-pytest-for-plone,
    │                    layers-scopes-and-isolation
    └── reference/       fixtures, markers, api
    

    reference/fixtures.md is a hybrid: curated grouping and an overview table by hand (autodoc cannot produce navigation), with one {autodoc2-object} per fixture pulling the docstring in. That follows the Plone docs rule that auto-generated docs alone are not sufficient — they need curating and organizing.

    The README then slims to a pointer (~80 lines: badges, install, a short quickstart, link to the docs), which is the double-maintenance problem you raised.

    Sequencing

    • Phase 1 — docs/ scaffold + conf.py, the full reference, the setup how-to, both explanation pages, make docs with -W, CI job.
    • Phase 2 — tutorial, remaining how-tos, and then slim the README (gutting it before the docs are complete would leave users worse off than today).
    • Deferred to their own issues — hosting (RTD vs. submodule), and Vale (bringing 620 lines of prose to Microsoft style is a project in itself and would swamp the PR).

    Happy to adjust the split. The one open question I would like your take on is hosting — given that the build needs no Plone, RTD looks a lot more attractive than it did.

  3. added a commit that references this issue on Jul 13, 2026
  4. added a commit that references this issue on Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationquestionFurther information is requested

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions