iiasa / message_ix

The integrated assessment and energy systems model MESSAGEix
https://docs.messageix.org
Apache License 2.0
112 stars 149 forks source link

Resolving documentation build warnings #758

Open glatterf42 opened 8 months ago

glatterf42 commented 8 months ago

As mentioned in #757, our docs are building successfully, though with several warnings:

reading sources... [  2%] api
Cannot locate code for 'message_ix.models.DEFAULT_CPLEX_OPTIONS' or parent class/module
Cannot locate code for 'message_ix.models.MESSAGE_ITEMS' or parent class/module
Cannot locate code for 'message_ix.macro.MACRO_ITEMS' or parent class/module
reading sources... [100%] whatsnew

/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/checkouts/latest/doc/api.rst:24: WARNING: autosummary: failed to import ixmp.testing.make_dantzig.
Possible hints:
* AttributeError: module 'ixmp' has no attribute 'testing'
* ModuleNotFoundError: No module named 'pytest'
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/checkouts/latest/doc/reporting.rst:282: WARNING: autosummary: failed to import genno.compat.pyam.computations.as_pyam.
Possible hints:
* AttributeError: module 'genno.compat.pyam' has no attribute 'computations'
* AttributeError: module 'message_ix.reporting.computations' has no attribute 'genno'
* ModuleNotFoundError: No module named 'genno.compat.pyam.computations'
* ModuleNotFoundError: No module named 'message_ix.reporting.computations.genno'; 'message_ix.reporting.computations' is not a package
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.add:8: ERROR: Undefined substitution referenced: "KeyLike".
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.add:8: ERROR: Undefined substitution referenced: "KeyLike".
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.check_keys:1: ERROR: Undefined substitution referenced: "KeyLike".
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.check_keys:19: ERROR: Undefined substitution referenced: "KeyLike".
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.infer_keys:1: ERROR: Undefined substitution referenced: "KeyLike".
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.infer_keys:1: ERROR: Undefined substitution referenced: "KeyLike".
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.infer_keys:17: ERROR: Undefined substitution referenced: "KeyLike".
/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.infer_keys:18: ERROR: Undefined substitution referenced: "KeyLike".
writing output... [100%] whatsnew

/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.cache:3: WARNING: unknown document: 'cache'
generating indices... /home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix/envs/latest/lib/python3.11/site-packages/message_ix/reporting/__init__.py:docstring of genno.core.computer.Computer.configure:8: WARNING: unknown document: 'config'

These warnings and errors probably mean that some aspects of our framework are not documented as expected, though most of that seems to be due to erroneous links. We should investigate how these links ought to look so that our documentation can be complete (again).

Possible sources for e.g. ixmp.testing missing:

khaeru commented 8 months ago

I also ran into some of these in iiasa/message-ix-models#122, and you can browse the fixes (only partial) I made on that branch.

Some notes:

My approach to fixing these was to run something like watchexec -- "make SPHINXOPTS='-E -n' html" and use batch search-and-replace to address the most common errors.

glatterf42 commented 8 months ago

Regarding the first part of the warnings,

reading sources... [  2%] api
Cannot locate code for 'message_ix.models.DEFAULT_CPLEX_OPTIONS' or parent class/module
Cannot locate code for 'message_ix.models.MESSAGE_ITEMS' or parent class/module
Cannot locate code for 'message_ix.macro.MACRO_ITEMS' or parent class/module

they originate from api.rst:L92-L94, as indicated. The issue here is that the sphinx extension directive autosummary mainly supports modules, classes, and functions: things that usually include some source code. Even with the latest version of sphinx, the objects are correctly identified, because some lines below, the .. autodata:: MESSAGE_DATA (and the rest) are rendered as intended. This is reassuring as the autodata directive is usually mentioned as the correct way to render dicts with sphinx. The only difference to the other things in the .. autosummary:: block in question, then, is that the other things (like MESSAGE and MACRO) are classes in message_ix.models.py. .. autosummary:: provides a :nosignatures: option to indicate that certain entries should be rendered without without signatures (but still with docstrings). However, I couldn't resolve the warnings by specifying :nosignatures: in the middle of the .. autosummary: nor at the beginning of a new, second one. There might be an option to use a custom template (e.g. the attribute one) and specify the objtype as data. However, I don't immediately know how to do that (probably involves copying the template file from the autosummary repo, adapating, renaming, and committing that to ours, and hoping that it resolves the warnings as intended) and while looking into this, I noticed that everything seems to be working as intended, despite these first warnings. So for now, I will not further try to resolve them.

glatterf42 commented 8 months ago

The precise source of the first group of warnings seems to be slightly off from what I described above. doc/reporting.rst includes

.. autosummary::

   DERIVED
   DIMS
   MAPPING_SETS
   PRODUCTS
   PYAM_CONVERT
   REPORTS

all of which are dicts, but none of which complain about missing source code. This shifts the error to the missing parent class/module, because the difference here is that all these dicts are part of message_ix/reporting/__init__.py. So to resolve the first group of errors, we might have to create a class in message_ix/models.py that can act as the parent for the dicts (or move them inside a module).

glatterf42 commented 8 months ago

Unfortunately, I don't think I have the time now to resolve all of these issues. I've created #759 with some commits containing fixes for the second group of warnings.

The other issues

The third and fourth group of errors/warnings originate from the interplay of message_ix with genno. Both complain about docstrings in genno/core/computer.py.

The third group of errors

One issue is with replacements: genno recently introduced several variables of the sort |Keylike| (e.g. here) that get replaced according to this specification in genno/doc/conf.py:

rst_prolog = """
.. role:: py(code)
   :language: python

.. |KeyLike| replace:: :obj:`~genno.core.key.KeyLike`
"""

Unfortunately, these don't seem to resolve correctly when mentioning :class:'~genno.Computer' (note: adapted to ') in message_ix, which happens in [macro.rst](https://github.com/glatterf42/message_ix/blob/e25f3dc474ff6815478c4d73d41874e09ff08c37/doc/macro.rst#L238) and [reporting.rst](https://github.com/glatterf42/message_ix/blob/e25f3dc474ff6815478c4d73d41874e09ff08c37/doc/reporting.rst#L32) ([twice](https://github.com/glatterf42/message_ix/blob/e25f3dc474ff6815478c4d73d41874e09ff08c37/doc/reporting.rst#L59-L60)). I don't know if there is a way to have message_ix recognize therst_prologof a linked documentation or if it should work out of the box. If this setting needs to be purposefully exposed to other projects, maybe this issue can only be resolved within genno. From the message-side, all references are in a text or table, where no additional information is needed, so there is no necessity to check all docstrings ofgenno.Computeror resolve them correctly as they link to the genno docs, where this problem doesn't exist. So from the message-side, it might suffice to replace the:class:` directive with something that only links to genno's docs.

The fourth group of warnings

The second issue is with references to documents within genno, so most likely the fix should also happen within genno. The references to the documents config and cache in genno/core/computer.py do not resolve successfully in message_ix. This is most likely due to the path being used for that being absolute, which works for the genno docs, but not for the message_ix docs. I'm not sure about two things: I don't know if these references should resolve correctly. This looks again like a reference within docstrings of genno.Computer, which are not themselves part of the message_ix docs, so it might be safe to ignore them on our side or use just a linking directive rather than :class: as discussed above. I'm also not sure why these warnings are emitted. First, this happens after all output has been written, apparently while generating indices. Second, the documents that can't be found are simply called 'config' and 'cache', so we try to access them as they are specified within the docstrings of genno.core.computer.py, which in genno get evaluated only with an additional .. currentmodule:: genno. If specifying a different directive doesn't work and they should resolve, maybe the paths in genno have to be adapted.