documenteer 2.5.0b2__tar.gz → 2.5.0b3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/PKG-INFO +1 -1
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260722_000000_jonathan_DM_55387_intersphinx_cache.md +1 -1
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260723_000000_jonathan_DM_55600_intersphinx_cache_ttl.md +1 -1
- documenteer-2.5.0b3/changelog.d/20260813_000000_jonathan_DM_55690_alias_metadata_fragments.md +3 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/toml-reference.rst +3 -3
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/autotypes.rst +5 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/conf/_toml.py +11 -13
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/autotypes/xrefs.py +135 -8
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer.egg-info/PKG-INFO +1 -1
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer.egg-info/SOURCES.txt +5 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer.egg-info/scm_file_list.json +5 -0
- documenteer-2.5.0b3/src/documenteer.egg-info/scm_version.json +8 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/autotypes_test.py +238 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/intersphinxcache_test.py +1 -1
- documenteer-2.5.0b3/tests/roots/test-autotypes-annotated/aliases.rst +17 -0
- documenteer-2.5.0b3/tests/roots/test-autotypes-annotated/aliaspkg/__init__.py +13 -0
- documenteer-2.5.0b3/tests/roots/test-autotypes-annotated/aliaspkg/_types.py +75 -0
- documenteer-2.5.0b3/tests/roots/test-autotypes-annotated/aliaspkg/legacy.py +32 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-annotated/index.rst +7 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/test_conf_toml.py +3 -3
- documenteer-2.5.0b2/src/documenteer.egg-info/scm_version.json +0 -8
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/project-mechanics/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-create-pr/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-fixup/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-implement/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-prd/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-prd-followup/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-prd-to-issues/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-rebase/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-review/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-run-workflow/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.agents/skills/stoker-work/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/project-mechanics/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-create-pr/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-fixup/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-implement/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-prd/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-prd-followup/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-prd-to-issues/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-rebase/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-review/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-run-workflow/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/skills/stoker-work/SKILL.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/tasks/.gitkeep +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.claude/workflows/stoker-iteration.js +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/Dockerfile +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/devcontainer.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/agent-entry.sh +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/codex-config.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/devcontainer.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/features/stoker-sandbox/devcontainer-feature.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/features/stoker-sandbox/install.sh +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/firewall-allowlist.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/firewall-refresh.cron +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.devcontainer/stoker/init-firewall.sh +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.flake8 +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/CODE_OF_CONDUCT.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/CONTRIBUTING.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/ISSUE_TEMPLATE/prd-task.yml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/ISSUE_TEMPLATE/prd.yml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/SUPPORT.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/dependabot.yml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/workflows/ci-cron.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.github/workflows/ci.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.npmrc +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.nvmrc +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.pre-commit-config.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.prettierignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.prettierrc.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.stoker/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.stoker/prompts/fixup.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.stoker/prompts/implement.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.stoker/prompts/rebase.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.stoker/prompts/review.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.stoker/prompts/select.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.stoker/settings.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.vscode/settings.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/.vscode/tasks.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/CHANGELOG.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/CLAUDE.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/LICENSE +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/MANIFEST.in +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/Makefile +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/README.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260629_000000_DM-55292-remote-code-block.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260629_000001_DM-55292-sphinx-upgrade.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260629_000002_DM-55292-diagrams.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260629_000003_DM-55292-diagrams-svg.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260629_155552_jonathan_DM_55292_upgrade.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260630_125651_jonathan_DM_55292_frontend.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260702_000000_DM-52076-technote-lint.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260706_000000_jonathan_DM_55386_linkcheck_service.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260727_000000_jonathan_DM_55634_github_edit_link_path.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260731_000000_jonathan_autotypes.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260801_000000_jonathan_git_shallow_suppress.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260806_000000_jonathan_DM_55745_improve_this_page.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260806_000001_jonathan_DM_55745_header_nav_wrap.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260806_000002_jonathan_DM_55745_github_icon.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260806_000003_jonathan_DM_55745_footer.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260807_000000_jonathan_DM_55745_drop_rubin_docs_link.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/20260812_000000_jonathan_DM_55690_sphinx9_gaps.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/changelog.d/_template.md.jinja +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/Makefile +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/diagram.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/extra-notebook.ipynb +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/index.ipynb +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/subdir/subdir-notebook.ipynb +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/ipynb-technote/technote.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/md-technote/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/md-technote/Makefile +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/md-technote/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/md-technote/diagram.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/md-technote/index.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/md-technote/technote.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/rst-technote/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/rst-technote/Makefile +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/rst-technote/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/rst-technote/diagram.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/rst-technote/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/rst-technote/local.bib +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/demo/rst-technote/technote.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/Makefile +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/_rst_epilog.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/changelog.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/api/documenteer.conf.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/api/documenteer.ext.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/api/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/dependency-policy.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/development.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/html-templates.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/release.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/theme-assets.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/dev/theme.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/documenteer.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/badges.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/configuration-preset.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/configuration.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/diagrams.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/extend-conf-py.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/improve-this-page.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/including-notebooks.ipynb +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/markdown-primer.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/openapi.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/organization.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/overview.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/page-redirects.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/pyproject-configuration.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/rst-epilog.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/tabsets.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/guides/video-embeds.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/docushare-reference.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/github-edit-link.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/githubbibcache.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/jira-reference.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/last-updated.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/lsst-pybtex-style.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/openapi.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/sphinx-extensions/remote-code-block.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/_templates/README.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/_templates/README.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/author-metadata.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/configuration.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/document-status.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/edit-locally.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/edit-on-github.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/extensions.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/how-your-technote-gets-published.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn001.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn002.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn003.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn004.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn005.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn006.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn101.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn102.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn103.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn201.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn202.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn203.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/lint/tn204.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/migrate.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/references.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/start-a-technote.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/docs/technotes/wide-content.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/licenses/README.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/licenses/astropy-helpers.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/licenses/sphinx-diagrams.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/licenses/sphinx-issue.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/licenses/sphinx.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/licenses/sphinxcontrib-redoc.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/noxfile.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/package-lock.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/package.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/postcss.config.js +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/pyproject.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/ruff-shared.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/setup.cfg +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-guide/styles/rubin-pydata-theme.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/SourceSans3VF-Italic.ttf.woff2 +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/SourceSans3VF-Upright.ttf.woff2 +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/_hacks.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/_properties.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/components/_article-header.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/components/_authors.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/components/_global-breadcrumbs.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/components/_index.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/components/_sidebar-section.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/components/_version-info.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/assets/rubin-technote/styles/rubin-technote.scss +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/_packagemetadata.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/_requestsutils.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/_utils.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/.gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/731c8feefe13e72a8691.woff2 +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/b8bc3440ba2145e132f5.woff2 +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/favicon.ico +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rsd-assets/rubin-imagotype-color-on-black-crop.svg +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rsd-assets/rubin-imagotype-color-on-white-crop.svg +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rsd-assets/rubin-partners.png +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-favicon-transparent-32px.png +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-favicon.svg +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-footer-align.js +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-last-modified.js +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-pydata-theme.css +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-pydata-theme.css.map +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-technote.css +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-technote.css.map +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-titlebar-imagotype-dark.svg +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/rubin-titlebar-imagotype-light.svg +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/scripts/rubin-pydata-theme.js +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/scripts/rubin-pydata-theme.js.map +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/scripts/rubin-technote.js +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/assets/scripts/rubin-technote.js.map +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/cli.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/conf/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/conf/_utils.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/conf/guide.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/conf/technote.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/autotypes/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/autotypes/_shared.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/autotypes/compat.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/autotypes/documenters.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/bibtex.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/diagrams.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/githubbibcache.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/githubeditlink.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/intersphinxcache.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/jira.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/lastmodified.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/linkcheckservice.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/lsstdocushare.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/mockcoderefs.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/openapi.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/redoc/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/redoc/_redoc.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/redoc/assets/redoc.html.jinja2 +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/remotecodeblock.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/ext/robots.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/py.typed +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/services/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/services/technoteauthor.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/services/technotelint.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/services/technotemigration.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/authordb.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/intersphinxcacheclient.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/latex.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/linkcheckclient.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/Makefile +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/README.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/ci.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/dependabot.yml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/gitignore +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/pre-commit-config.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/requirements.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates/technote/tox.ini +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/localtemplates.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/storage/technotetoml.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/autosummary_core/exception.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/autosummary_core/pydantic_model.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/components/prev-next.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/last-updated.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/layout.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/rubin-footer.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/rubin-improve-this-page.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/pydata/rubin-print-footer.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/technote/.gitkeep +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/technote/components/.gitkeep +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/technote/components/sidebar-source.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/technote/sections/.gitkeep +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/technote/sections/header-article.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/templates/technote/sections/sidebar-primary.html +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer/version.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer.egg-info/dependency_links.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer.egg-info/entry_points.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer.egg-info/requires.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/documenteer.egg-info/top_level.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/src/sphinx_diagrams/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/cli_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/conftest.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/afw.doxygen.conf +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/authordb.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/doxygen.tag.zip +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_alpha/doc/_static/package_alpha/README.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_alpha/doc/doxygen.conf.in +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_alpha/doc/manifest.yaml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_alpha/doc/package.alpha/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_alpha/doc/package_alpha/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_alpha/include/README.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_alpha/src/README.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/data/package_beta/doc/README.md +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/conftest.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/diagrams_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/githubeditlink_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/guide_build_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/jira_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/lastmodified_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/linkcheckservice_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/lsstdocushare_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/mockcoderefs_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/redoc_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/ext/robots_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/packagemetadata_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autocppapi/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autocppapi/doxygen.tag.zip +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autocppapi/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes/_templates/autosummary_core/pydantic_model.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes/autotypespkg/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes/autotypespkg/_impl.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-alias/aliasroot/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-alias/aliasroot/documented/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-alias/aliasroot/documented/helpers.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-alias/aliasroot/external/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-alias/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-alias/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-annotated/annotatedpkg/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-annotated/annotatedpkg/constrained.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-annotated/annotatedpkg/phased.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-annotated/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-annotated/extphase/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-inherited/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-inherited/extpkg/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-inherited/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-inherited/inheritpkg/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-private/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-private/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-private/privatepkg/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-private/privatepkg/_impl.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-private/privatepkg/helpers.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-pydantic/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-pydantic/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-pydantic/pydanticpkg/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-typehints/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-typehints/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-autotypes-typehints/singletonpkg/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-diagrams/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-diagrams/diagram.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-diagrams/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-diagrams-svg/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-diagrams-svg/diagram.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-diagrams-svg/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-guide/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-guide/documenteer.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-guide/hidden.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-guide/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-intersphinx-cache/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-intersphinx-cache/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-intersphinx-cache-multi/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-intersphinx-cache-multi/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-intersphinx-cache-oddkey/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-intersphinx-cache-oddkey/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-lastmodified/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-lastmodified/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-lastmodified/page2.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-lastmodified/snippet.txt +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service/documenteer.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-filter/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-filter/documenteer.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-filter/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-multipage/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-multipage/documenteer.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-multipage/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-multipage/page-a.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-linkcheck-service-multipage/page-b.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-redoc/_static/openapi.json +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-redoc/api.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-redoc/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-redoc/documenteer.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-redoc/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-robots-nositemap/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-robots-nositemap/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-robots-nositemap/page1.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-robots-sitemap/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-robots-sitemap/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-robots-sitemap/page1.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-robots-sitemap/page2.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-technote-linkcheck-service/conf.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-technote-linkcheck-service/index.rst +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/roots/test-technote-linkcheck-service/technote.toml +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/services/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/services/technotelint_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/services/technotemigration_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/storage/__init__.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/storage/authordb_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/storage/intersphinxcacheclient_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/storage/linkcheckclient_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/storage/technotetoml_test.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/test_conf_utils.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/tests/test_git_repository.py +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/uv.lock +0 -0
- {documenteer-2.5.0b2 → documenteer-2.5.0b3}/webpack.config.js +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
### New features
|
|
2
2
|
|
|
3
|
-
- Documentation builds now prefetch intersphinx object inventories from Ook's inventory cache service, so builds no longer depend on third-party site availability to resolve cross-references. The new `documenteer.ext.intersphinxcache` extension — registered by both the user-guide and technote configuration presets — runs before `sphinx.ext.intersphinx` processes its mapping: it fetches each entry's `objects.inv` from the service, writes it to the build directory, and rewrites that entry's inventory location to the local file. Target URIs are left unchanged, so resolved links still point at the upstream sites. Prefetching authenticates with a bearer token from `OOK_TOKEN`; when the token is unset (fork pull requests, local builds) the extension is a complete no-op, and any per-inventory service failure (unauthorized, unreachable, server error, timeout) falls back to a direct origin fetch, reported at the `INFO` log level (not as a warning, so warnings-as-errors `-W` builds don't fail on graceful service degradation), so an Ook outage can never make a build worse than stock intersphinx. New `[sphinx.
|
|
3
|
+
- Documentation builds now prefetch intersphinx object inventories from Ook's inventory cache service, so builds no longer depend on third-party site availability to resolve cross-references. The new `documenteer.ext.intersphinxcache` extension — registered by both the user-guide and technote configuration presets — runs before `sphinx.ext.intersphinx` processes its mapping: it fetches each entry's `objects.inv` from the service, writes it to the build directory, and rewrites that entry's inventory location to the local file. Target URIs are left unchanged, so resolved links still point at the upstream sites. Prefetching authenticates with a bearer token from `OOK_TOKEN`; when the token is unset (fork pull requests, local builds) the extension is a complete no-op, and any per-inventory service failure (unauthorized, unreachable, server error, timeout) falls back to a direct origin fetch, reported at the `INFO` log level (not as a warning, so warnings-as-errors `-W` builds don't fail on graceful service degradation), so an Ook outage can never make a build worse than stock intersphinx. New `[sphinx.intersphinx.cache]` settings in `documenteer.toml` configure the integration for guides (`use_service`, `service_url`); technotes use the defaults and can override the corresponding `documenteer_intersphinx_cache_*` values in `conf.py` after the preset import.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
### New features
|
|
2
2
|
|
|
3
|
-
- Prefetched intersphinx inventories are now cached on disk with a short time-to-live (the new `disk_cache_ttl` setting under `[sphinx.
|
|
3
|
+
- Prefetched intersphinx inventories are now cached on disk with a short time-to-live (the new `disk_cache_ttl` setting under `[sphinx.intersphinx.cache]`, default 600 seconds; `0` disables it), so rapid successive local rebuilds reuse the cached `objects.inv` without contacting Ook at all. Once the TTL expires, Documenteer revalidates conditionally: it sends the stored ETag as an `If-None-Match` header, and a `304 Not Modified` reuses the on-disk copy with no inventory body transferred (a `200 OK` replaces it). Technotes can override the TTL through `documenteer_intersphinx_cache_disk_cache_ttl` in `conf.py`.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
### Bug fixes
|
|
2
|
+
|
|
3
|
+
- `documenteer.ext.autotypes` no longer warns about the reference targets Sphinx synthesizes out of a *type alias's own* `Annotated` value. Safir's `type IvoaIsoDatetime = Annotated[datetime, BeforeValidator(...), PlainSerializer(..., when_used="json")]` is the shape: Sphinx renders the alias's value onto its page (and into every signature the alias annotates), stringifying each dataclass metadata field, and then unparses the result into a reference per fragment — leaking `PydanticUndefined` (the repr of `BeforeValidator`'s sentinel default) and `json` (the unquoted string value of `when_used`) as nitpick warnings. The existing fragments rung could not cover them because it rebuilds the fragments of a documented *class's* metadata, while an alias page carries no `py:class` context at all. A module-scoped sibling index now rebuilds the fragments that the `Annotated` aliases of the reference's `py:module` context module render — both a PEP 695 `type` statement and an assignment-style `Annotated` alias — and degrades those names to unlinked literal text. Like its class-scoped sibling it resolves nothing and is consulted only after every resolution rung has already failed, so a name no alias of that module renders — a typo of a real fragment included — keeps warning, and a fragment of one module's alias does not degrade under another module's context.
|
|
@@ -503,7 +503,7 @@ The values are URLs to the root of Sphinx documentation projects.
|
|
|
503
503
|
|
|
504
504
|
See the Intersphinx_ documentation for details on linking to other Sphinx projects.
|
|
505
505
|
|
|
506
|
-
[sphinx.
|
|
506
|
+
[sphinx.intersphinx.cache]
|
|
507
507
|
==========================
|
|
508
508
|
|
|
509
509
|
|optional|
|
|
@@ -543,7 +543,7 @@ Set this to ``false`` as an escape hatch to disable prefetching so Intersphinx_
|
|
|
543
543
|
|
|
544
544
|
.. code-block:: toml
|
|
545
545
|
|
|
546
|
-
[sphinx.
|
|
546
|
+
[sphinx.intersphinx.cache]
|
|
547
547
|
use_service = false
|
|
548
548
|
|
|
549
549
|
With ``use_service = false`` the service is never contacted, even when an ``OOK_TOKEN`` is set.
|
|
@@ -576,7 +576,7 @@ Set ``disk_cache_ttl`` to ``0`` to disable this fast path so every build revalid
|
|
|
576
576
|
|
|
577
577
|
.. code-block:: toml
|
|
578
578
|
|
|
579
|
-
[sphinx.
|
|
579
|
+
[sphinx.intersphinx.cache]
|
|
580
580
|
disk_cache_ttl = 0
|
|
581
581
|
|
|
582
582
|
The TTL governs only the client-to-Ook hop; whether Ook's own cached copy is current relative to the origin site remains Ook's concern.
|
|
@@ -136,6 +136,11 @@ The annotated *type* is deliberately excluded, so it keeps following the ordinar
|
|
|
136
136
|
|
|
137
137
|
.. [#source] ``sphinx.util.typing.get_type_hints`` falls back to a class's raw ``__annotations__`` when evaluating them raises, and autodoc first copies each base class's *source* annotations onto the class — which is enough to make that fallback fire on a Pydantic model. Under ``from __future__ import annotations`` those raw annotations are :pep:`563` strings, so the annotation is rendered exactly as written.
|
|
138
138
|
|
|
139
|
+
The same fragment family reaches a **type alias's own page**, where the reference carries no ``py:class`` context for that rung to read — only the ``py:module`` of the module the alias is documented from.
|
|
140
|
+
Safir's ``type IvoaIsoDatetime = Annotated[datetime, BeforeValidator(…), PlainSerializer(…, when_used="json")]`` is the case that motivated this: Sphinx renders the alias's whole value onto its stub page — and into every signature the alias annotates, since an assignment-style alias knows neither its own name nor its module — leaking ``PydanticUndefined``, the repr of ``BeforeValidator``\ ’s sentinel default, and a bare ``json`` from the unquoted ``when_used`` value.
|
|
141
|
+
A module-scoped sibling index therefore rebuilds the fragments that the ``Annotated`` aliases of the reference's ``py:module`` context render, covering both alias spellings: a :pep:`695` ``type`` statement whose value is (or contains) an ``Annotated`` form, and an assignment-style ``Annotated`` alias.
|
|
142
|
+
It resolves nothing either, and is consulted only after the class-scoped rung has failed as well, so the guardrail is the same one module out — a name that no alias of that module renders keeps warning, and a fragment of one module's alias does not degrade under another module's context.
|
|
143
|
+
|
|
139
144
|
Anything else is left alone, so genuine mistakes (a typo'd module path that fails to import, a reference to something in this project's public API that should be exported and documented but isn't) still surface as nitpick warnings.
|
|
140
145
|
|
|
141
146
|
Sub-extensions
|
|
@@ -171,14 +171,6 @@ class ProjectModel(BaseModel):
|
|
|
171
171
|
openapi: OpenApiDocsModel | None = Field(None)
|
|
172
172
|
|
|
173
173
|
|
|
174
|
-
class IntersphinxModel(BaseModel):
|
|
175
|
-
"""Model for Intersphinx configurations in documenteer.toml."""
|
|
176
|
-
|
|
177
|
-
projects: dict[str, HttpUrl] = Field(
|
|
178
|
-
description="Mapping of projects and their URLs.", default_factory=dict
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
|
|
182
174
|
class IntersphinxCacheModel(BaseModel):
|
|
183
175
|
"""Model for the Ook intersphinx inventory cache configuration in
|
|
184
176
|
documenteer.toml.
|
|
@@ -214,6 +206,16 @@ class IntersphinxCacheModel(BaseModel):
|
|
|
214
206
|
)
|
|
215
207
|
|
|
216
208
|
|
|
209
|
+
class IntersphinxModel(BaseModel):
|
|
210
|
+
"""Model for Intersphinx configurations in documenteer.toml."""
|
|
211
|
+
|
|
212
|
+
projects: dict[str, HttpUrl] = Field(
|
|
213
|
+
description="Mapping of projects and their URLs.", default_factory=dict
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
cache: IntersphinxCacheModel = Field(default_factory=IntersphinxCacheModel)
|
|
217
|
+
|
|
218
|
+
|
|
217
219
|
class LinkCheckModel(BaseModel):
|
|
218
220
|
"""Model for linkcheck builder configurations in documenteer.toml."""
|
|
219
221
|
|
|
@@ -354,10 +356,6 @@ class SphinxModel(BaseModel):
|
|
|
354
356
|
|
|
355
357
|
intersphinx: IntersphinxModel = Field(default_factory=IntersphinxModel)
|
|
356
358
|
|
|
357
|
-
intersphinx_cache: IntersphinxCacheModel = Field(
|
|
358
|
-
default_factory=IntersphinxCacheModel
|
|
359
|
-
)
|
|
360
|
-
|
|
361
359
|
linkcheck: LinkCheckModel = Field(default_factory=LinkCheckModel)
|
|
362
360
|
|
|
363
361
|
redirects: dict[str, str] = Field(
|
|
@@ -555,7 +553,7 @@ class DocumenteerConfig:
|
|
|
555
553
|
[sphinx] table is not set.
|
|
556
554
|
"""
|
|
557
555
|
if self.conf.sphinx:
|
|
558
|
-
return self.conf.sphinx.
|
|
556
|
+
return self.conf.sphinx.intersphinx.cache
|
|
559
557
|
return IntersphinxCacheModel()
|
|
560
558
|
|
|
561
559
|
@property
|
|
@@ -36,8 +36,11 @@ resolution policy:
|
|
|
36
36
|
``repr()`` that happens to *parse* as Python is split into fragments
|
|
37
37
|
instead of mangled, so the fragments of a documented class's own
|
|
38
38
|
``Annotated`` metadata (``Ge``, ``file``, ``ExecutionPhase.PENDING``)
|
|
39
|
-
degrade too
|
|
40
|
-
|
|
39
|
+
degrade too — as do the fragments of a *type alias's* own ``Annotated``
|
|
40
|
+
value (``PydanticUndefined``, ``json``), which surface on pages carrying
|
|
41
|
+
only a ``py:module`` context and are therefore recognized per module
|
|
42
|
+
rather than per class. Project-local objects under wholly public module
|
|
43
|
+
paths keep warning: those are the ones that should be exported and
|
|
41
44
|
documented, so they stay visible.
|
|
42
45
|
|
|
43
46
|
- Modules documented with ``automodapi::`` and ``:no-main-docstr:`` get a
|
|
@@ -244,10 +247,20 @@ def _project_typing_registry(
|
|
|
244
247
|
return registry
|
|
245
248
|
|
|
246
249
|
|
|
250
|
+
def _import_module(modname: str) -> types.ModuleType | None:
|
|
251
|
+
"""Import ``modname``, or return None."""
|
|
252
|
+
try:
|
|
253
|
+
return importlib.import_module(modname)
|
|
254
|
+
except Exception:
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
|
|
247
258
|
def _import_from_module(modname: str, attrname: str) -> Any | None:
|
|
248
259
|
"""Import ``modname`` and return its ``attrname`` attribute, or None."""
|
|
260
|
+
module = _import_module(modname)
|
|
261
|
+
if module is None:
|
|
262
|
+
return None
|
|
249
263
|
try:
|
|
250
|
-
module = importlib.import_module(modname)
|
|
251
264
|
return getattr(module, attrname, None)
|
|
252
265
|
except Exception:
|
|
253
266
|
return None
|
|
@@ -1168,16 +1181,115 @@ def _annotated_metadata_fragments(
|
|
|
1168
1181
|
if isinstance(value, str):
|
|
1169
1182
|
fragments |= _source_metadata_names(value)
|
|
1170
1183
|
continue
|
|
1171
|
-
|
|
1172
|
-
for rendering in _render_metadata_object(metadata):
|
|
1173
|
-
tree = _parse_expression(rendering)
|
|
1174
|
-
if tree is not None:
|
|
1175
|
-
fragments |= _expression_names(tree)
|
|
1184
|
+
fragments |= _runtime_metadata_fragments(value)
|
|
1176
1185
|
result = frozenset(fragments)
|
|
1177
1186
|
by_class[id(cls)] = result
|
|
1178
1187
|
return result
|
|
1179
1188
|
|
|
1180
1189
|
|
|
1190
|
+
def _runtime_metadata_fragments(value: Any) -> set[str]:
|
|
1191
|
+
"""Collect the names Sphinx's rendering of *value*'s metadata emits.
|
|
1192
|
+
|
|
1193
|
+
Every ``Annotated`` form nested in *value* contributes the names of
|
|
1194
|
+
both renderings its metadata objects can take
|
|
1195
|
+
(:func:`_render_metadata_object`), for the renderings that parse as
|
|
1196
|
+
Python — the ones Sphinx's annotation parser splits into fragments
|
|
1197
|
+
rather than mangling whole (:func:`_is_mangled_target`).
|
|
1198
|
+
"""
|
|
1199
|
+
fragments: set[str] = set()
|
|
1200
|
+
for metadata in _iter_annotated_metadata(value, set()):
|
|
1201
|
+
for rendering in _render_metadata_object(metadata):
|
|
1202
|
+
tree = _parse_expression(rendering)
|
|
1203
|
+
if tree is not None:
|
|
1204
|
+
fragments |= _expression_names(tree)
|
|
1205
|
+
return fragments
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
def _module_alias_values(modname: str) -> list[Any]:
|
|
1209
|
+
"""Collect the alias values a module exposes publicly.
|
|
1210
|
+
|
|
1211
|
+
Both alias shapes a module can publish are read, since Sphinx renders
|
|
1212
|
+
the metadata of either into the alias's own page: a :pep:`695`
|
|
1213
|
+
``type`` statement, whose ``TypeAliasType`` is unwrapped to the
|
|
1214
|
+
(lazily evaluated) value it stands for, and an assignment-style
|
|
1215
|
+
``Annotated`` alias, which *is* its value
|
|
1216
|
+
(:func:`~documenteer.ext.autotypes._shared._is_annotated_alias`).
|
|
1217
|
+
|
|
1218
|
+
Only public attributes count, and every probe is guarded: evaluating
|
|
1219
|
+
a lazy alias value can raise (a ``type`` statement naming something
|
|
1220
|
+
undefined), and reading an arbitrary module attribute can raise
|
|
1221
|
+
anything at all (Pydantic's mock validators raise
|
|
1222
|
+
``PydanticUserError``).
|
|
1223
|
+
"""
|
|
1224
|
+
module = _import_module(modname)
|
|
1225
|
+
if module is None:
|
|
1226
|
+
return []
|
|
1227
|
+
try:
|
|
1228
|
+
attrs = dict(vars(module))
|
|
1229
|
+
except TypeError:
|
|
1230
|
+
return []
|
|
1231
|
+
values: list[Any] = []
|
|
1232
|
+
for attr, value in attrs.items():
|
|
1233
|
+
if attr.startswith("_"):
|
|
1234
|
+
continue
|
|
1235
|
+
if isinstance(value, TypeAliasType):
|
|
1236
|
+
with contextlib.suppress(Exception):
|
|
1237
|
+
values.append(value.__value__)
|
|
1238
|
+
elif _is_annotated_alias(value):
|
|
1239
|
+
values.append(value)
|
|
1240
|
+
return values
|
|
1241
|
+
|
|
1242
|
+
|
|
1243
|
+
_alias_fragment_cache: dict[int, dict[str, frozenset[str]]] = {}
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
def _alias_metadata_fragments(
|
|
1247
|
+
modname: str, env: BuildEnvironment | None = None
|
|
1248
|
+
) -> frozenset[str]:
|
|
1249
|
+
"""Index the names a module's alias ``Annotated`` metadata synthesizes.
|
|
1250
|
+
|
|
1251
|
+
This is the module-scoped sibling of
|
|
1252
|
+
:func:`_annotated_metadata_fragments`, and it exists because the same
|
|
1253
|
+
fragments surface in a second place: a type alias's *own* page.
|
|
1254
|
+
Sphinx renders the alias's value there, metadata and all, and unparses
|
|
1255
|
+
the result into cross-references — so Safir's ``IvoaIsoDatetime``,
|
|
1256
|
+
whose value carries a ``BeforeValidator`` and a ``PlainSerializer``,
|
|
1257
|
+
emits a ``PydanticUndefined`` (the repr of a sentinel default) and a
|
|
1258
|
+
``json`` (the unquoted string value of ``when_used="json"``) target.
|
|
1259
|
+
Those describe how a value is validated and serialized; neither names
|
|
1260
|
+
anything that could be documented.
|
|
1261
|
+
|
|
1262
|
+
The class-scoped rung cannot cover them: an alias page carries no
|
|
1263
|
+
``py:class`` context at all, only the ``py:module`` of the module the
|
|
1264
|
+
alias is documented from. That module — not the alias's defining
|
|
1265
|
+
module — is therefore what this is indexed by, and it is the whole
|
|
1266
|
+
guardrail: a name that no alias of *this* module renders keeps
|
|
1267
|
+
warning, and a fragment of one module's alias does not degrade under
|
|
1268
|
+
another module's context.
|
|
1269
|
+
|
|
1270
|
+
Like its class-scoped sibling the index resolves nothing, so it adds
|
|
1271
|
+
no lookup surface: it is consulted only after every resolution rung,
|
|
1272
|
+
and the class-scoped rung, have already failed. It is cached per
|
|
1273
|
+
build environment and module, following
|
|
1274
|
+
:func:`_annotated_metadata_fragments`.
|
|
1275
|
+
"""
|
|
1276
|
+
key = id(env)
|
|
1277
|
+
by_module = _alias_fragment_cache.get(key)
|
|
1278
|
+
if by_module is None:
|
|
1279
|
+
_alias_fragment_cache.clear()
|
|
1280
|
+
by_module = {}
|
|
1281
|
+
_alias_fragment_cache[key] = by_module
|
|
1282
|
+
cached = by_module.get(modname)
|
|
1283
|
+
if cached is not None:
|
|
1284
|
+
return cached
|
|
1285
|
+
fragments: set[str] = set()
|
|
1286
|
+
for value in _module_alias_values(modname):
|
|
1287
|
+
fragments |= _runtime_metadata_fragments(value)
|
|
1288
|
+
result = frozenset(fragments)
|
|
1289
|
+
by_module[modname] = result
|
|
1290
|
+
return result
|
|
1291
|
+
|
|
1292
|
+
|
|
1181
1293
|
def _missing_reference( # noqa: C901, PLR0912
|
|
1182
1294
|
app: Sphinx,
|
|
1183
1295
|
env: BuildEnvironment,
|
|
@@ -1315,6 +1427,21 @@ def _missing_reference( # noqa: C901, PLR0912
|
|
|
1315
1427
|
if cls is not None and base in _annotated_metadata_fragments(cls, env):
|
|
1316
1428
|
return contnode
|
|
1317
1429
|
|
|
1430
|
+
# The same fragment family on a *type alias's* own page, where the
|
|
1431
|
+
# reference carries no ``py:class`` context for the rung above to read
|
|
1432
|
+
# — only the ``py:module`` of the module the alias is documented from.
|
|
1433
|
+
# Safir's ``IvoaIsoDatetime`` is the case: its value's
|
|
1434
|
+
# ``BeforeValidator``/``PlainSerializer`` metadata renders a
|
|
1435
|
+
# ``PydanticUndefined`` sentinel repr and an unquoted ``json`` string
|
|
1436
|
+
# value into the alias's rendered value, and Sphinx unparses both into
|
|
1437
|
+
# targets. Unlinked literal, not a warning. Only names some alias of
|
|
1438
|
+
# *this* module renders count, so names from elsewhere keep warning.
|
|
1439
|
+
module_context = node.get("py:module")
|
|
1440
|
+
if module_context and base in _alias_metadata_fragments(
|
|
1441
|
+
module_context, env
|
|
1442
|
+
):
|
|
1443
|
+
return contnode
|
|
1444
|
+
|
|
1318
1445
|
return None
|
|
1319
1446
|
|
|
1320
1447
|
|
|
@@ -90,6 +90,7 @@ changelog.d/20260806_000002_jonathan_DM_55745_github_icon.md
|
|
|
90
90
|
changelog.d/20260806_000003_jonathan_DM_55745_footer.md
|
|
91
91
|
changelog.d/20260807_000000_jonathan_DM_55745_drop_rubin_docs_link.md
|
|
92
92
|
changelog.d/20260812_000000_jonathan_DM_55690_sphinx9_gaps.md
|
|
93
|
+
changelog.d/20260813_000000_jonathan_DM_55690_alias_metadata_fragments.md
|
|
93
94
|
changelog.d/_template.md.jinja
|
|
94
95
|
demo/ipynb-technote/.gitignore
|
|
95
96
|
demo/ipynb-technote/Makefile
|
|
@@ -344,8 +345,12 @@ tests/roots/test-autotypes-alias/aliasroot/__init__.py
|
|
|
344
345
|
tests/roots/test-autotypes-alias/aliasroot/documented/__init__.py
|
|
345
346
|
tests/roots/test-autotypes-alias/aliasroot/documented/helpers.py
|
|
346
347
|
tests/roots/test-autotypes-alias/aliasroot/external/__init__.py
|
|
348
|
+
tests/roots/test-autotypes-annotated/aliases.rst
|
|
347
349
|
tests/roots/test-autotypes-annotated/conf.py
|
|
348
350
|
tests/roots/test-autotypes-annotated/index.rst
|
|
351
|
+
tests/roots/test-autotypes-annotated/aliaspkg/__init__.py
|
|
352
|
+
tests/roots/test-autotypes-annotated/aliaspkg/_types.py
|
|
353
|
+
tests/roots/test-autotypes-annotated/aliaspkg/legacy.py
|
|
349
354
|
tests/roots/test-autotypes-annotated/annotatedpkg/__init__.py
|
|
350
355
|
tests/roots/test-autotypes-annotated/annotatedpkg/constrained.py
|
|
351
356
|
tests/roots/test-autotypes-annotated/annotatedpkg/phased.py
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"changelog.d/20260806_000003_jonathan_DM_55745_footer.md",
|
|
85
85
|
"changelog.d/20260807_000000_jonathan_DM_55745_drop_rubin_docs_link.md",
|
|
86
86
|
"changelog.d/20260812_000000_jonathan_DM_55690_sphinx9_gaps.md",
|
|
87
|
+
"changelog.d/20260813_000000_jonathan_DM_55690_alias_metadata_fragments.md",
|
|
87
88
|
"changelog.d/_template.md.jinja",
|
|
88
89
|
"demo/ipynb-technote/.gitignore",
|
|
89
90
|
"demo/ipynb-technote/Makefile",
|
|
@@ -318,6 +319,10 @@
|
|
|
318
319
|
"tests/roots/test-autotypes-alias/aliasroot/external/__init__.py",
|
|
319
320
|
"tests/roots/test-autotypes-alias/conf.py",
|
|
320
321
|
"tests/roots/test-autotypes-alias/index.rst",
|
|
322
|
+
"tests/roots/test-autotypes-annotated/aliases.rst",
|
|
323
|
+
"tests/roots/test-autotypes-annotated/aliaspkg/__init__.py",
|
|
324
|
+
"tests/roots/test-autotypes-annotated/aliaspkg/_types.py",
|
|
325
|
+
"tests/roots/test-autotypes-annotated/aliaspkg/legacy.py",
|
|
321
326
|
"tests/roots/test-autotypes-annotated/annotatedpkg/__init__.py",
|
|
322
327
|
"tests/roots/test-autotypes-annotated/annotatedpkg/constrained.py",
|
|
323
328
|
"tests/roots/test-autotypes-annotated/annotatedpkg/phased.py",
|
|
@@ -20,6 +20,8 @@ from documenteer.ext.autotypes.documenters import (
|
|
|
20
20
|
)
|
|
21
21
|
from documenteer.ext.autotypes.xrefs import (
|
|
22
22
|
_AMBIGUOUS,
|
|
23
|
+
_alias_fragment_cache,
|
|
24
|
+
_alias_metadata_fragments,
|
|
23
25
|
_annotated_metadata_fragments,
|
|
24
26
|
_candidate_names,
|
|
25
27
|
_is_mangled_target,
|
|
@@ -434,6 +436,94 @@ def test_autotypes_annotated_metadata_negatives(app: SphinxTestApp) -> None:
|
|
|
434
436
|
assert resolve("ExecutionPhase.PENDING", "SentryConfig") is None
|
|
435
437
|
|
|
436
438
|
|
|
439
|
+
def _object_entry(html: str, object_id: str) -> str:
|
|
440
|
+
"""Return the whole markup of one documented object.
|
|
441
|
+
|
|
442
|
+
An alias's value is rendered in its *body* rather than in its
|
|
443
|
+
signature line (the ``py:type`` directive's ``:canonical:`` option
|
|
444
|
+
becomes an "alias of" paragraph), so the slice runs to the end of the
|
|
445
|
+
definition rather than to the end of the signature.
|
|
446
|
+
"""
|
|
447
|
+
start = html.index(f'id="{object_id}"')
|
|
448
|
+
return html[start : html.index("</dd>", start)]
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
@pytest.mark.sphinx(
|
|
452
|
+
"html", testroot="autotypes-annotated", srcdir="autotypes-alias-metadata"
|
|
453
|
+
)
|
|
454
|
+
def test_autotypes_alias_metadata(app: SphinxTestApp, warning) -> None:
|
|
455
|
+
"""Fragments of an alias's own Annotated metadata degrade to text."""
|
|
456
|
+
app.build()
|
|
457
|
+
assert "reference target not found" not in warning.getvalue()
|
|
458
|
+
|
|
459
|
+
html = (app.outdir / "aliases.html").read_text()
|
|
460
|
+
|
|
461
|
+
# The rendered alias values below are fully degraded, so the only
|
|
462
|
+
# anchor in each entry is its own ¶ headerlink.
|
|
463
|
+
def entry(name: str) -> str:
|
|
464
|
+
markup = _object_entry(html, f"aliaspkg.{name}")
|
|
465
|
+
assert markup.count("<a") == markup.count('<a class="headerlink"')
|
|
466
|
+
return markup
|
|
467
|
+
|
|
468
|
+
# The PEP 695 alias: ``PydanticUndefined`` is the repr of a dataclass
|
|
469
|
+
# metadata field's sentinel default, and ``json`` is another field's
|
|
470
|
+
# string value, stringified into the rendering without its quotes.
|
|
471
|
+
iso = entry("IsoDatetime")
|
|
472
|
+
assert ">PydanticUndefined<" in iso
|
|
473
|
+
assert ">json<" in iso
|
|
474
|
+
|
|
475
|
+
# The assignment-style alias, documented as data. Sphinx renders its
|
|
476
|
+
# whole value into the signature of the function it annotates — an
|
|
477
|
+
# assignment alias knows neither its name nor its module — so the same
|
|
478
|
+
# metadata fragments surface there, under the same module-only context.
|
|
479
|
+
assert 'id="aliaspkg.TrimmedName"' in html
|
|
480
|
+
register = entry("register")
|
|
481
|
+
assert ">PydanticUndefined<" in register
|
|
482
|
+
assert ">always<" in register
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
@pytest.mark.sphinx(
|
|
486
|
+
"html",
|
|
487
|
+
testroot="autotypes-annotated",
|
|
488
|
+
srcdir="autotypes-alias-metadata-neg",
|
|
489
|
+
)
|
|
490
|
+
def test_autotypes_alias_metadata_negatives(app: SphinxTestApp) -> None:
|
|
491
|
+
"""Names no alias rendering in the context module produces still warn."""
|
|
492
|
+
app.build()
|
|
493
|
+
|
|
494
|
+
def resolve(target: str, module: str) -> nodes.Element | None:
|
|
495
|
+
contnode = nodes.literal("", target)
|
|
496
|
+
node = addnodes.pending_xref(
|
|
497
|
+
"",
|
|
498
|
+
contnode,
|
|
499
|
+
refdomain="py",
|
|
500
|
+
reftype="class",
|
|
501
|
+
reftarget=target,
|
|
502
|
+
**{"py:module": module},
|
|
503
|
+
)
|
|
504
|
+
return _missing_reference(app, app.env, node, contnode)
|
|
505
|
+
|
|
506
|
+
# The fragments themselves degrade under the module the aliases are
|
|
507
|
+
# documented from — from the PEP 695 alias and, for ``always``, from
|
|
508
|
+
# the assignment-style one.
|
|
509
|
+
assert resolve("PydanticUndefined", "aliaspkg") is not None
|
|
510
|
+
assert resolve("json", "aliaspkg") is not None
|
|
511
|
+
assert resolve("always", "aliaspkg") is not None
|
|
512
|
+
|
|
513
|
+
# A typo of a fragment is in no alias's rendering, so it still warns.
|
|
514
|
+
assert resolve("PydanticUndefinde", "aliaspkg") is None
|
|
515
|
+
assert resolve("jsonl", "aliaspkg") is None
|
|
516
|
+
|
|
517
|
+
# The index is per module: ``aliaspkg.legacy``'s own alias renders
|
|
518
|
+
# neither the sentinel default nor the ``always`` string value, so a
|
|
519
|
+
# fragment of the package's aliases does not degrade under it.
|
|
520
|
+
assert resolve("PydanticUndefined", "aliaspkg.legacy") is None
|
|
521
|
+
assert resolve("always", "aliaspkg.legacy") is None
|
|
522
|
+
|
|
523
|
+
# A module with no ``Annotated`` alias at all degrades nothing.
|
|
524
|
+
assert resolve("PydanticUndefined", "annotatedpkg") is None
|
|
525
|
+
|
|
526
|
+
|
|
437
527
|
@pytest.mark.sphinx("html", testroot="autotypes-typehints")
|
|
438
528
|
def test_autotypes_callable_singleton(app: SphinxTestApp, warning) -> None:
|
|
439
529
|
"""A module-level callable singleton survives the build."""
|
|
@@ -1176,6 +1266,154 @@ def test_annotated_metadata_fragments_misses() -> None:
|
|
|
1176
1266
|
)
|
|
1177
1267
|
|
|
1178
1268
|
|
|
1269
|
+
def _iso_normalize(value: str) -> str:
|
|
1270
|
+
"""Stand in for Safir's ``normalize_isodatetime`` validator function.
|
|
1271
|
+
|
|
1272
|
+
A module-level function is what the rendering under test needs: Sphinx
|
|
1273
|
+
writes a dataclass metadata field's value with
|
|
1274
|
+
``stringify_annotation``, which renders a function as its dotted
|
|
1275
|
+
``module.qualname``. A nested function's qualname carries
|
|
1276
|
+
``<locals>``, whose angle brackets would make the whole rendering
|
|
1277
|
+
unparseable and leave no fragments at all.
|
|
1278
|
+
"""
|
|
1279
|
+
return value
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
def _iso_render(value: object) -> str:
|
|
1283
|
+
"""Stand in for Safir's ``isodatetime`` serializer function."""
|
|
1284
|
+
return str(value)
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
def _validator_alias_value() -> object:
|
|
1288
|
+
"""Build the ``Annotated`` form of Safir's ``IvoaIsoDatetime``.
|
|
1289
|
+
|
|
1290
|
+
``BeforeValidator.json_schema_input_type`` defaults to the
|
|
1291
|
+
``PydanticUndefined`` sentinel and ``PlainSerializer.when_used`` is a
|
|
1292
|
+
string, so Sphinx's field-by-field rendering of these two dataclasses
|
|
1293
|
+
is what emits the ``PydanticUndefined`` and ``json`` targets that
|
|
1294
|
+
issue #385 reports as nitpick warnings.
|
|
1295
|
+
"""
|
|
1296
|
+
from datetime import datetime # noqa: PLC0415
|
|
1297
|
+
from typing import Annotated # noqa: PLC0415
|
|
1298
|
+
|
|
1299
|
+
from pydantic import BeforeValidator, PlainSerializer # noqa: PLC0415
|
|
1300
|
+
|
|
1301
|
+
return Annotated[
|
|
1302
|
+
datetime,
|
|
1303
|
+
BeforeValidator(_iso_normalize),
|
|
1304
|
+
PlainSerializer(_iso_render, return_type=str, when_used="json"),
|
|
1305
|
+
]
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
@pytest.fixture
|
|
1309
|
+
def clear_alias_fragment_cache():
|
|
1310
|
+
"""Isolate the module-scoped alias fragment index's cache.
|
|
1311
|
+
|
|
1312
|
+
The index is keyed by ``id(env)`` and then by module name, and these
|
|
1313
|
+
unit tests pass no environment at all — so without this they would
|
|
1314
|
+
all share the ``id(None)`` bucket and could be served another test's
|
|
1315
|
+
synthetic module under the same name.
|
|
1316
|
+
"""
|
|
1317
|
+
_alias_fragment_cache.clear()
|
|
1318
|
+
yield
|
|
1319
|
+
_alias_fragment_cache.clear()
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
def test_alias_metadata_fragments_type_alias(
|
|
1323
|
+
monkeypatch, clear_alias_fragment_cache
|
|
1324
|
+
) -> None:
|
|
1325
|
+
"""A PEP 695 alias's own ``Annotated`` metadata supplies fragments."""
|
|
1326
|
+
from typing import TypeAliasType # noqa: PLC0415
|
|
1327
|
+
|
|
1328
|
+
_install_modules(
|
|
1329
|
+
monkeypatch,
|
|
1330
|
+
{
|
|
1331
|
+
"aliasfragprobe": {
|
|
1332
|
+
"IsoDatetime": TypeAliasType(
|
|
1333
|
+
"IsoDatetime", _validator_alias_value()
|
|
1334
|
+
)
|
|
1335
|
+
}
|
|
1336
|
+
},
|
|
1337
|
+
)
|
|
1338
|
+
|
|
1339
|
+
fragments = _alias_metadata_fragments("aliasfragprobe")
|
|
1340
|
+
|
|
1341
|
+
# The sentinel-object default and the unquoted string field value.
|
|
1342
|
+
assert {"PydanticUndefined", "json"} <= fragments
|
|
1343
|
+
|
|
1344
|
+
# The annotated type is not metadata, so it keeps following the
|
|
1345
|
+
# ordinary resolution ladder rather than degrading here.
|
|
1346
|
+
assert "datetime.datetime" not in fragments
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
def test_alias_metadata_fragments_assignment_alias(
|
|
1350
|
+
monkeypatch, clear_alias_fragment_cache
|
|
1351
|
+
) -> None:
|
|
1352
|
+
"""An assignment-style ``Annotated`` module alias contributes too."""
|
|
1353
|
+
from typing import Annotated # noqa: PLC0415
|
|
1354
|
+
|
|
1355
|
+
from pydantic import BeforeValidator # noqa: PLC0415
|
|
1356
|
+
|
|
1357
|
+
_install_modules(
|
|
1358
|
+
monkeypatch,
|
|
1359
|
+
{
|
|
1360
|
+
"aliasfragprobe": {
|
|
1361
|
+
"TrimmedName": Annotated[str, BeforeValidator(_iso_normalize)]
|
|
1362
|
+
}
|
|
1363
|
+
},
|
|
1364
|
+
)
|
|
1365
|
+
|
|
1366
|
+
fragments = _alias_metadata_fragments("aliasfragprobe")
|
|
1367
|
+
|
|
1368
|
+
assert "PydanticUndefined" in fragments
|
|
1369
|
+
assert "aliasfragprobe.other" not in fragments
|
|
1370
|
+
|
|
1371
|
+
# ``str`` is the annotated type here, not a metadata rendering.
|
|
1372
|
+
assert "str" not in fragments
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
def test_alias_metadata_fragments_misses(
|
|
1376
|
+
monkeypatch, clear_alias_fragment_cache
|
|
1377
|
+
) -> None:
|
|
1378
|
+
"""Names no alias rendering in the module produces are not fragments."""
|
|
1379
|
+
from typing import Annotated, TypeAliasType # noqa: PLC0415
|
|
1380
|
+
|
|
1381
|
+
from pydantic import PlainSerializer # noqa: PLC0415
|
|
1382
|
+
|
|
1383
|
+
_install_modules(
|
|
1384
|
+
monkeypatch,
|
|
1385
|
+
{
|
|
1386
|
+
"aliasfragprobe": {
|
|
1387
|
+
"IsoDatetime": TypeAliasType(
|
|
1388
|
+
"IsoDatetime", _validator_alias_value()
|
|
1389
|
+
),
|
|
1390
|
+
"_Hidden": Annotated[
|
|
1391
|
+
str,
|
|
1392
|
+
PlainSerializer(_iso_render, when_used="unless_none"),
|
|
1393
|
+
],
|
|
1394
|
+
"MAX_LENGTH": 64,
|
|
1395
|
+
},
|
|
1396
|
+
"aliasfragprobe.other": {"Loader": type("Loader", (), {})},
|
|
1397
|
+
},
|
|
1398
|
+
)
|
|
1399
|
+
|
|
1400
|
+
fragments = _alias_metadata_fragments("aliasfragprobe")
|
|
1401
|
+
|
|
1402
|
+
# A typo of a fragment, and a real but unrelated class, keep warning.
|
|
1403
|
+
assert "jsonl" not in fragments
|
|
1404
|
+
assert "ModuleAnalyzer" not in fragments
|
|
1405
|
+
|
|
1406
|
+
# Only public attributes are scanned, so a private alias's own
|
|
1407
|
+
# fragments are not admitted.
|
|
1408
|
+
assert "unless_none" not in fragments
|
|
1409
|
+
|
|
1410
|
+
# The index is per module: a sibling module with no ``Annotated``
|
|
1411
|
+
# alias of its own produces nothing, and neither does a module that
|
|
1412
|
+
# cannot be imported at all.
|
|
1413
|
+
assert _alias_metadata_fragments("aliasfragprobe.other") == frozenset()
|
|
1414
|
+
assert _alias_metadata_fragments("nosuchaliasprobe") == frozenset()
|
|
1415
|
+
|
|
1416
|
+
|
|
1179
1417
|
def test_strip_bogus_typing_prefix() -> None:
|
|
1180
1418
|
# PEP 695 scoped type parameters that sphinx-autodoc-typehints
|
|
1181
1419
|
# qualified with a bogus ``typing.`` prefix.
|
|
@@ -945,7 +945,7 @@ def test_guide_preset_registers_extension(
|
|
|
945
945
|
monkeypatch: Any,
|
|
946
946
|
) -> None:
|
|
947
947
|
"""The guide preset registers the intersphinxcache extension and wires
|
|
948
|
-
the [sphinx.
|
|
948
|
+
the [sphinx.intersphinx.cache] settings through to its config values.
|
|
949
949
|
"""
|
|
950
950
|
monkeypatch.delenv("OOK_TOKEN", raising=False)
|
|
951
951
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Alias-metadata fragments
|
|
2
|
+
========================
|
|
3
|
+
|
|
4
|
+
.. automodule:: aliaspkg
|
|
5
|
+
|
|
6
|
+
Both alias spellings, documented from the package that re-exports them,
|
|
7
|
+
plus a function annotated with the assignment-style one. Sphinx renders
|
|
8
|
+
each alias's whole ``Annotated`` value — validator and serializer metadata
|
|
9
|
+
included — into the alias's own page and into that signature, where a
|
|
10
|
+
reference carries no ``py:class`` context at all, only this module's
|
|
11
|
+
``py:module``.
|
|
12
|
+
|
|
13
|
+
.. autotype:: aliaspkg.IsoDatetime
|
|
14
|
+
|
|
15
|
+
.. autodata:: aliaspkg.TrimmedName
|
|
16
|
+
|
|
17
|
+
.. autofunction:: aliaspkg.register
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""A package documenting the aliases it re-exports from a private module.
|
|
2
|
+
|
|
3
|
+
This mirrors ``safir.pydantic``, which publishes ``IvoaIsoDatetime`` from
|
|
4
|
+
``safir.pydantic._types``: an alias page's ``py:module`` context is the
|
|
5
|
+
package the alias is documented *from*, never the module it was written
|
|
6
|
+
in, which is the module the fragment index has to be keyed by.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from ._types import IsoDatetime, TrimmedName, register
|
|
12
|
+
|
|
13
|
+
__all__ = ["IsoDatetime", "TrimmedName", "register"]
|