Skip to content

docs: Reduce Sphinx build warnings and fix broken links - #7526

Merged
wenzeslaus merged 15 commits into
OSGeo:mainfrom
neteler:sphinx_docs_fixes
Jul 13, 2026
Merged

wenzeslaus merged 15 commits into
OSGeo:mainfrom
neteler:sphinx_docs_fixes

Conversation

@neteler

@neteler neteler commented Jun 8, 2026 •

Copy link
Copy Markdown
Member

I played around with the terminal based OpenCode tool, a open source AI coding agent (https://opencode.ai/).
To try something hopefully useful, I let it fix the broken crosslinks in the sphinx based docs, using DeepSeek Flash free.

Goal: let make sphinxdoclib run free of errors and warnings.
A critical review is desired.

Original warnings and errors:

make sphinxdoclib
[...]
Running Sphinx v9.1.0
loading translations [en]... done
Converting `source_suffix = '.rst'` to `source_suffix = {'.rst': 'restructuredtext'}`.
WARNING: The config value `today' has type `date'; expected `str'.
[...]
<unknown>:1: WARNING: duplicate object description of grass.pygrass.modules.interface.module.Module, other instance in grass.pygrass.modules, use :no-index: for one of them
<unknown>:1: WARNING: duplicate object description of grass.pygrass.modules.interface.module.MultiModule, other instance in grass.pygrass.modules, use :no-index: for one of them
<unknown>:1: WARNING: duplicate object description of grass.pygrass.modules.interface.module.ParallelModuleQueue, other instance in grass.pygrass.modules, use :no-index: for one of them
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_algebra.py:docstring of grass.temporal.temporal_algebra.TemporalAlgebraLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_operator.py:docstring of grass.temporal.temporal_operator.TemporalOperatorLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_algebra.py:docstring of grass.temporal.temporal_algebra.TemporalAlgebraLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_operator.py:docstring of grass.temporal.temporal_operator.TemporalOperatorLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
/home/mneteler/software/grass_main/python/grass/docs/src/index.rst:42: WARNING: toctree contains reference to nonexisting document 'index' [toc.not_readable]
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_algebra.py:docstring of temporal.temporal_algebra.TemporalAlgebraLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_operator.py:docstring of temporal.temporal_operator.TemporalOperatorLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_algebra.py:docstring of temporal.temporal_algebra.TemporalAlgebraLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
/home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/etc/python/grass/temporal/temporal_operator.py:docstring of temporal.temporal_operator.TemporalOperatorLexer.t_NAME:1: ERROR: Unknown target name: "a-za-z". [docutils]
looking for now-outdated files... none found
pickling environment... WARNING: cannot cache unpickleable configuration value: 'html_context' (because it contains a function, class, or module object) [config.cache]
done
checking consistency... /home/mneteler/software/grass_main/python/grass/docs/src/grass.rst: WARNING: document isn't included in any toctree [toc.not_included]
/home/mneteler/software/grass_main/python/grass/docs/src/temporal_framework.rst: WARNING: document isn't included in any toctree [toc.not_included]
/home/mneteler/software/grass_main/python/grass/docs/src/grass.jupyter.rst: document is referenced in multiple toctrees: ['grass', 'index'], selecting: index <- grass.jupyter
/home/mneteler/software/grass_main/python/grass/docs/src/grass.tools.rst: document is referenced in multiple toctrees: ['grass', 'index'], selecting: index <- grass.tools
done
preparing documents... WARNING: unsupported theme option 'logo' given
done
copying assets... 
copying downloadable files... [100%] Temporal-Framework-API-Description.pdf
copying static files... 
Writing evaluated template result to /home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/docs/html/libpython/_static/basic.css
Writing evaluated template result to /home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/docs/html/libpython/_static/documentation_options.js
Writing evaluated template result to /home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/docs/html/libpython/_static/language_data.js
Writing evaluated template result to /home/mneteler/software/grass_main/dist.x86_64-pc-linux-gnu/docs/html/libpython/_static/material.css
copying static files: done
copying extra files... 
copying extra files: done
copying assets: done
writing output... [100%] temporal_framework
<unknown>:1: WARNING: more than one target found for cross-reference 'GrassTestFilesMultiReporter': grass.gunittest.reporters.GrassTestFilesMultiReporter, gunittest.reporters.GrassTestFilesMultiReporter [ref.python]
/home/mneteler/software/grass_main/python/grass/docs/src/grass.pydispatch.rst:13: WARNING: more than one target found for cross-reference 'errors.DispatcherTypeError': grass.pydispatch.errors.DispatcherTypeError, pydispatch.errors.DispatcherTypeError [ref.python]
/home/mneteler/software/grass_main/python/grass/docs/src/grass.pydispatch.rst:13: WARNING: more than one target found for cross-reference 'errors.DispatcherTypeError': grass.pydispatch.errors.DispatcherTypeError, pydispatch.errors.DispatcherTypeError [ref.python]
/home/mneteler/software/grass_main/python/grass/docs/src/grass.pydispatch.rst:13: WARNING: more than one target found for cross-reference 'errors.DispatcherKeyError': grass.pydispatch.errors.DispatcherKeyError, pydispatch.errors.DispatcherKeyError [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'GrassTestFilesMultiReporter': grass.gunittest.reporters.GrassTestFilesMultiReporter, gunittest.reporters.GrassTestFilesMultiReporter [ref.python]
/home/mneteler/software/grass_main/python/grass/docs/src/pydispatch.rst:8: WARNING: more than one target found for cross-reference 'errors.DispatcherTypeError': grass.pydispatch.errors.DispatcherTypeError, pydispatch.errors.DispatcherTypeError [ref.python]
/home/mneteler/software/grass_main/python/grass/docs/src/pydispatch.rst:8: WARNING: more than one target found for cross-reference 'errors.DispatcherTypeError': grass.pydispatch.errors.DispatcherTypeError, pydispatch.errors.DispatcherTypeError [ref.python]
/home/mneteler/software/grass_main/python/grass/docs/src/pydispatch.rst:8: WARNING: more than one target found for cross-reference 'errors.DispatcherKeyError': grass.pydispatch.errors.DispatcherKeyError, pydispatch.errors.DispatcherKeyError [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
<unknown>:1: WARNING: more than one target found for cross-reference 'Table': grass.pygrass.vector.table.Table, pygrass.vector.table.Table [ref.python]
generating indices... genindex py-modindex done

This PR collects the sphinx code changes:

.rst fixes (cross-references, toctree, unused labels):

  • index.rst: fixes broken relative links (../python_intro.html, ../jupyter_intro.html); added exceptions and temporal_framework to the toctree (were producing document isn't included in any toctree warnings); removed duplicate toctree entries (grass.tools, grass.jupyter, grass.exceptions) that were already covered by the parent grass entry
  • gunittest_testing.rst: renamed duplicate label GRASS sample data to GRASS sample data testing to resolve sphinx duplicate label conflict with gunittest_running_tests.rst; removed unused test-as-scripts and doctest label definitions
  • pygrass_gis.rst: removed unused GRASSdatabase-label and Region-label definitions
  • pygrass_raster.rst: removed unused raster-label definition

conf.py fixes (config errors, lexer docstrings, theme options):

  • fixed today type mismatch (date → str via .strftime())
  • added autodoc_mock_imports = ["grass.lib", "grass.lib.gis"] to mock C extension modules during autodoc
  • added skip_member filter to skip PLY lexer t_* methods in temporal_algebra and temporal_operator (their regex docstrings are not intended for RST parsing, were causing Unknown target name errors).
  • added pickleable html_context proxy to replace sphinx_material theme class objects (TableFix, DerenderToc) which sphinx cannot cache (fixes cannot cache unpickleable configuration value warning).
  • removed unsupported logo option from html_theme_options.

Template fix (duplicate object descriptions):

  • package.rst.jinja: Added :no-index: to automodule directives for subpackages and submodules in the auto-generated API docs template. The root grass package keeps full index entries; subpackages use :no-index: to avoid duplicating entries already generated by the parent.

If acceptable (as is or modified), I recommend to backport it to G85.

Fix Sphinx build warnings and broken cross-references

`.rst` fixes (cross-references, toctree, unused labels):
- `index.rst`: fixes broken relative links (`../python_intro.html`, `../jupyter_intro.html`); added `exceptions` and `temporal_framework` to the toctree (were producing document isn't included in any toctree warnings); removed duplicate toctree entries (`grass.tools`, `grass.jupyter`, `grass.exceptions`) that were already covered by the parent `grass` entry
- `gunittest_testing.rst`: renamed duplicate label `GRASS sample data` to `GRASS sample data testing` to resolve sphinx `duplicate label` conflict with `gunittest_running_tests.rst`; removed unused `test-as-scripts` and `doctest` label definitions
- `pygrass_gis.rst`: removed unused `GRASSdatabase-label` and `Region-label` definitions
- `pygrass_raster.rst`: removed unused `raster-label` definition

`conf.py` fixes (config errors, lexer docstrings, theme options):
- fixed `today` type mismatch (`date` → `str` via `.strftime()`)
- added `autodoc_mock_imports = ["grass.lib", "grass.lib.gis"]` to mock C extension modules during autodoc
- added `skip_member` filter to skip PLY lexer `t_*` methods in `temporal_algebra` and `temporal_operator` (their regex docstrings are not intended for RST parsing, were causing `Unknown target name` errors).
- added pickleable `html_context` proxy to replace `sphinx_material` theme class objects (`TableFix`, `DerenderToc`) which sphinx cannot cache (fixes `cannot cache unpickleable configuration value` warning).
- removed unsupported logo option from `html_theme_options`.

Template fix (duplicate object descriptions):
- `package.rst.jinja`: Added `:no-index:` to automodule directives for subpackages and submodules in the auto-generated API docs template. The root `grass` package keeps full index entries; subpackages use `:no-index:` to avoid duplicating entries already generated by the parent.
@neteler neteler added this to the 8.6.0 milestone Jun 8, 2026
@neteler neteler self-assigned this Jun 8, 2026
@neteler neteler added the docs label Jun 8, 2026
Comment thread python/grass/docs/src/index.rst Resolved
Comment thread python/grass/docs/conf.py Resolved
Comment thread python/grass/docs/conf.py Resolved
@github-actions github-actions Bot added Python Related code is in Python libraries labels Jun 8, 2026
Comment thread python/grass/docs/conf.py Resolved
@echoix echoix mentioned this pull request Jun 17, 2026
8 tasks done
@echoix

echoix commented Jul 6, 2026 •

Copy link
Copy Markdown
Member

I checked the diff of the artifact I refreshed yesterday, vs the one on main. See #7526 (comment). Some links to code are now gone. The navigation added at the bottom is nice. The TOC of individual pages has less items in it now, it doesn't matter that much. I didn't look at all the pages

Revert the no-index template change: the :no-index: option removes
cross-reference targets, not just index entries, and because sphinx-apidoc
also runs per subpackage (root package names pygrass, exceptions, etc.),
it removed the link targets from nearly every generated page. This
restores the hyperlinks reported missing in the PR review at the cost of
re-admitting three duplicate object description warnings caused by
re-exports in grass.pygrass.modules.

Remove autodoc_mock_imports: the docs build runs inside a GRASS session
where grass.lib is importable, and mocking a real module distorts the
documented pygrass classes that use ctypes structures.

Make the GRASS sample data references actual links (a trailing underscore
is required; with default_role literal they rendered as code) and remove
the parenthetical tarball name from the link target, where docutils would
join it into a malformed URL.

Keep the exceptions bullet and toctree pointing to the same legacy page,
and keep the conventional toctree indentation.

The changes were reviewed and generated with Claude Code.
@wenzeslaus

Copy link
Copy Markdown
Member

AI summary of the current state:

I pushed df04c67 to this branch (maintainer edit) applying the fixes worked out in wenzeslaus#11:

  • Reverts the package.rst.jinja :no-index: change (file now identical to main). :no-index: removes cross-reference targets, not just index entries, and it ended up applied to nearly every generated page — this is what broke the hyperlinks @echoix and @neteler observed. The revert restores the links at the cost of re-admitting the three "duplicate object description" warnings.
  • Removes autodoc_mock_imports: grass.lib is importable during the docs build, and mocking a real module distorts the documented pygrass classes.
  • Fixes the "GRASS sample data" references: adds the trailing underscore so they are actual links (with default_role = "literal" they rendered as code), and cleans the target URLs.
  • index.rst: keeps the toctree fixes, restores 3-space indentation, keeps bullet and toctree consistently on the legacy exceptions page.

Verification (docs built from this branch): all warnings this PR targets are gone, and the generated HTML confirms the cross-reference links are back.

Remaining warnings (out of scope here):

  • html_context unpickleable — from sphinx_material theme classes; the proxy workaround was already reverted since it did not help.
  • duplicate object description (3x) and more than one target found — root cause is that every module is documented twice (per-subpackage apidoc runs with legacy unprefixed names, plus the run over the whole grass package). Follow-up: drop the legacy generation, keeping only grass.* names.
  • Genuine docstring markup issues in pydispatch/dispatcher.py, pygrass/raster/abstract.py, pygrass/vector/geometry.py, gunittest/runner.py, grass/tools/session_tools.py, imaging/images2avi.py — small fixes for a separate PR.
  • Found during verification: grass.temporal.unit_tests is broken on main — it imports adjust_datetime_to_granularity from .temporal_granularity, but the function lives in datetime_math.py; needs a one-line import fix (or excluding that legacy module from apidoc).

@wenzeslaus wenzeslaus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While there are still warnings the generated index (below) and the other changes look good to me.

Image

@neteler neteler added the backport to 8.5 PR needs to be backported to release branch 8.5 label Jul 13, 2026
@wenzeslaus
wenzeslaus enabled auto-merge (squash) July 13, 2026 09:48
@wenzeslaus wenzeslaus changed the title docs: fix sphinx build warnings and broken cross-references docs: Reduce Sphinx build warnings and fix broken links Jul 13, 2026
@wenzeslaus
wenzeslaus merged commit f9ae02a into OSGeo:main Jul 13, 2026
27 checks passed
@neteler
neteler deleted the sphinx_docs_fixes branch July 13, 2026 11:07
neteler added a commit that referenced this pull request Jul 13, 2026
Fix the today config type, skip PLY lexer docstrings in autodoc, remove
the unsupported logo theme option, correct the toctree entries, and make
the sample data links work again.

The initial changes were AI-assisted (OpenCode with DeepSeek), the review
and follow-up fixes used Claude Code (with Fable).

---------

Co-authored-by: Edouard Choinière <27212526+echoix@users.noreply.github.com>
Co-authored-by: Vaclav Petras <wenzeslaus@gmail.com>
@neteler neteler removed the backport to 8.5 PR needs to be backported to release branch 8.5 label Jul 13, 2026
@neteler neteler modified the milestones: 8.6.0, 8.5.1 Jul 13, 2026
echoix added a commit to wenzeslaus/grass that referenced this pull request Jul 14, 2026
Fix the today config type, skip PLY lexer docstrings in autodoc, remove
the unsupported logo theme option, correct the toctree entries, and make
the sample data links work again.

The initial changes were AI-assisted (OpenCode with DeepSeek), the review
and follow-up fixes used Claude Code (with Fable).

---------

Co-authored-by: Edouard Choinière <27212526+echoix@users.noreply.github.com>
Co-authored-by: Vaclav Petras <wenzeslaus@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs libraries Python Related code is in Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants