sphinx-test
An example Python project with sphinx documentation to demonstrate a warning about a missing attribute.
The warning can be triggered with:
sphinx-build -b html docs build
This produces this output:
Running Sphinx v5.3.0
loading pickled environment... done
[autosummary] generating autosummary for: index.rst, stubs/test_project.Base.attr.rst, stubs/test_project.Base.rst, stubs/test_project.Child.rst
WARNING: [autosummary] failed to import test_project.Child.attr.
Possible hints:
* AttributeError: type object 'Child' has no attribute 'attr'
* ModuleNotFoundError: No module named 'test_project.Child'
* ImportError:
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 0 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
no targets are out of date.
build succeeded, 1 warning.
Additionally, the documentation for Child
does not include the inherited attr
attribute (the documentation for Base
does include it).
The problem is that Sphinx detects the docstring on the attr
attribute defined in __init__
here:
class Base:
"""Parent class"""
def __init__(self):
self.attr = 0
"""Base class attribute"""
but then fails to find the attribute on the class that inherits from Base
here:
class Child(Base):
"""Child class"""
def print_attr(self):
"""Print attr value"""
print(self.attr)
It seems like sphinx just imports the module and inspects the class attributes, so it does not find instance attributes defined in __init__
(or at not ones defined in an inherited __init__
).
The template code in class.rst
that searches for the attribute is:
{% for item in all_attributes %}
{%- if not item.startswith('_') %}
{{ name }}.{{ item }}
{%- endif -%}
{%- endfor %}
Replacing this with
{% for item in attributes %}
.. autoattribute:: {{ item }}
{%- endfor %}
bypasses the warning but also does not document attr
for Base
or Child
.