readthedocs / sphinx-autoapi

A new approach to API documentation in Sphinx.
https://sphinx-autoapi.readthedocs.io/
MIT License
415 stars 126 forks source link

Issue in 3.1.1: Handler <function run_autoapi at 0x7c590c5005e0> for event 'builder-inited' threw an exception (exception: [Errno 2] No such file or directory #448

Open castlez opened 1 month ago

castlez commented 1 month ago

This is new as of today, i have a build from yesterday that built the docs ok. Ive mentioned this in https://github.com/readthedocs/sphinx-autoapi/issues/441 but ill reiterate here for completeness.

Just another data point here, i get the same thing if i run in a venv but not if i use system python (granted i still get an error, but i think its unrelated to this issue)

versions:

➜  python --version
Python 3.11.9
---------------
➜  pip freeze
...
Sphinx==7.3.7
sphinx-autoapi==3.1.1
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.8
sphinxcontrib-devhelp==1.0.6
sphinxcontrib-htmlhelp==2.0.5
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.7
sphinxcontrib-serializinghtml==1.1.10
...

Here's installing deps:

➜ pip install sphinx
➜ pip install sphinx_rtd_theme
➜ pip install sphinx-autoapi

Here's the commands

➜  tree .
.
├── build
│   └── _static
│       ├── jquery.js
│       └── _sphinx_javascript_frameworks_compat.js
├── code_src
│   ├── dummy.py
│   ├── __init__.py
│   └── __pycache__
│       ├── dummy.cpython-311.pyc
│       └── __init__.cpython-311.pyc
├── docs
│   ├── make.bat
│   ├── Makefile
│   └── source
│       ├── conf.py
│       └── index.rst
├── main.py
└── requirements.txt
➜  cd docs/source
➜  sphinx-build -b html . ../../build

and lastly here's the conf.py

# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
templates_path = ["_templates"]
source_suffix = ".rst"
master_doc = "index"
suppress_warnings = ["autoapi"]

project = 'GitRequester'
copyright = '2024, Castle'
author = 'Castle'
release = '1.0.0'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    'autoapi.extension',
    'sphinx.ext.viewcode'
]

autoapi_type = 'python'
autoapi_dirs = ['../../code_src']
autoapi_file_pattern = "*.py"
autoapi_options = ['members', 'private-members', 'show-inheritance',
                   'show-module-summary', 'special-members', 'imported-members', ]

exclude_patterns = ['build', 'Thumbs.db', '.DS_Store']
pygments_style = "sphinx"

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

Here's the output, this was not happening yesterday before this went in https://github.com/readthedocs/sphinx-autoapi/commit/eecb6e892aeefce249f46b90b49ccab3dd37133c (I am not 100% confident this change made it happen, i just see a correlation between this going in and this issue)

➜  sphinx-build -b html . ../../build
Running Sphinx v7.3.7
WARNING: html_static_path entry '_static' does not exist
[AutoAPI] Reading files... [100%] /home/castle/src/sphinx_poc/code_src/__init__.py
[AutoAPI] Mapping Data... [100%] /home/castle/src/sphinx_poc/code_src/__init__.py
[AutoAPI] Rendering Data...

Extension error (autoapi.extension):
Handler <function run_autoapi at 0x7cced9cfc5e0> for event 'builder-inited' threw an exception (exception: [Errno 2] No such file or directory: '/home/castle/src/sphinx_poc/docs/source/autoapi/index.rst')

For what its worth, i have been using sphinx-autoapi for a while now, and only recently started seeing this. Hard to pinpoint because i dont redeploy docs everyday, but definitely in the last month this came up.

Not sure why its looking in docs/source/autoapi/index.rst thats never where the index has been

castlez commented 1 month ago

Just confirmed that pinning sphinx-autoapi to version 3.1.0 solves the issue, meaning it was indeed something (somehow) in the 3.1.1 release. Looking at the code, i dont know enough to be able to pin point it, but im more confident its in there somewhere now. Gonna update the issue title to reflect that

alexfikl commented 1 month ago

This just started happening to me too recently. It seems like the issue is that build_finished tries to delete the autoapi_root here https://github.com/readthedocs/sphinx-autoapi/blob/8001fbd6d80492253eb0dd8ef7753f9adf21fc57/autoapi/extension.py#L149-L159 but it fails, since the folder does not exist on my system, not sure why. I've worked around it by adding this to conf.py

autoapi_keep_files = True

but it would be nice to know why this started happening and what's wrong in my config :\

sachahu1 commented 2 weeks ago

I just ran into the same issue, here's what I found:

I believe the autoapi_options that is causing all this fuss is "undoc-members". It is present in the default value but if you remove it sphinx-autoapi doesn't produce rst files for anything "undocumented".

So what counts as undocumented?

The short answer is: every module needs a docstring.

  1. If you have a nicely documented function in file.py but no "module" docstring, nothing from that file will show up.
  2. If file.py has a module docstring but lives inside a package whose __init__.py doesn't have a module docstring, nothing will show up.

So for something to be documented by autoapi, all of his parents need to be documented and they must all have module docstrings. So in the project below, for anything from schema_one.py to show up, you will need to have docstrings as follows:

doc_test_project/
├── another_module.py
├── cli.py
├── __init__.py <-- Module docstring
└── schemas
    ├── __init__.py <-- Module docstring
    └── schema_one.py <-- Document function + module

The solution

Either add module docstrings everywhere (or find some other solution to force autoapi to document these files) or add the "undoc-members" option back into the autoapi_options list

Actual permanent fix

From a code point of view, I'm still trying to trace down the origin of the problem but I think the problem stems from here: https://github.com/readthedocs/sphinx-autoapi/blob/8001fbd6d80492253eb0dd8ef7753f9adf21fc57/autoapi/_mapper.py#L337-L343

I think due to the parameters, self.objects_to_render.items() ends up being empty.

This seems to be caused by https://github.com/readthedocs/sphinx-autoapi/blob/eecb6e892aeefce249f46b90b49ccab3dd37133c/autoapi/_objects.py#L222-L242 returning True for everything.

I would expect even modules without a top-level module docstring should still be documented by autoapi.

@alexfikl (Tagged you since it might answer your question)

Let me know if that helps!

alexfikl commented 2 weeks ago

@sachahu1 Can confirm that adding back undoc-members to autoapi_options fixes this for me. Thank you for the explanation!

AWhetter commented 1 week ago

I think that it's legitimate for a module with no docstring to not get rendered unless undoc-members is set. undoc-members can be a useful control for what gets documented and what doesn't, and this functionality should extend to modules as well. It's not great that this behaviour changed in a minor release though. It probably warranted a major release, so apologies for the disruption caused. As for this error, it seems to come up when no module is documented and index injection occurs. AutoAPI should raise a more friendly error or warning in this case.