Skip to content

Commit acad72b

Browse files
committed
Gracefully handle no objects being rendered
Closes #448
1 parent d2a9675 commit acad72b

File tree

9 files changed

+89
-7
lines changed

9 files changed

+89
-7
lines changed

autoapi/_mapper.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,16 @@ def _output_top_rst(self):
359359
# Render Top Index
360360
top_level_index = os.path.join(self.dir_root, "index.rst")
361361
pages = [obj for obj in self.objects_to_render.values() if obj.display]
362+
if not pages:
363+
msg = (
364+
"No modules were rendered. "
365+
"Do you need to set autoapi_options to render additional objects?"
366+
)
367+
LOGGER.warning(
368+
msg, type="autoapi", subtype="nothing_rendered"
369+
)
370+
return
371+
362372
with open(top_level_index, "wb") as top_level_file:
363373
content = self.jinja_env.get_template("index.rst")
364374
top_level_file.write(content.render(pages=pages).encode("utf-8"))

autoapi/extension.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ def build_finished(app, exception):
124124
normalized_root = os.path.normpath(
125125
os.path.join(app.srcdir, app.config.autoapi_root)
126126
)
127+
if not os.path.exists(normalized_root):
128+
return
129+
127130
if app.verbosity > 1:
128131
LOGGER.info(
129132
colorize("bold", "[AutoAPI] ")

docs/changes/448.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Gracefully handle no objects being rendered

docs/reference/config.rst

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,19 @@ Suppressing Warnings
273273
274274
If narrower suppression is wanted, the available subtypes for AutoAPI are:
275275

276-
* python_import_resolution
277-
Used if resolving references to objects in an imported module failed. Potential reasons
278-
include cyclical imports and missing (parent) modules.
279-
* not_readable
280-
Emitted if processing (opening, parsing, ...) an input file failed.
281-
* toc_reference
282-
Used if a reference to an entry in a table of content cannot be resolved.
276+
* ``python_import_resolution``:
277+
Emitted if resolving references to objects in an imported module failed.
278+
Potential reasons include cyclical imports and missing (parent) modules.
279+
* ``not_readable``:
280+
Emitted if processing (opening, parsing, ...) an input file failed.
281+
* ``toc_reference``:
282+
Emitted if a reference to an entry in a table of content cannot be resolved.
283+
* ``nothing_rendered``:
284+
Emitted if nothing was found to be documented.
285+
Potential reasons include no files being found in :confval:`autoapi_dirs`
286+
that match :confval:`autoapi_file_patterns`,
287+
or all discovered modules and objects being excluded from rendering due to
288+
:confval:`autoapi_options` or :ref:`other rendering exclusions <customise-documented-api>`.
283289

284290
So if all AutoAPI warnings concerning unreadable sources and failing Python imports should be
285291
filtered, but all other warnings should not, the option would be

tests/python/pynorender/conf.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
templates_path = ["_templates"]
2+
source_suffix = ".rst"
3+
master_doc = "index"
4+
project = "pyexample"
5+
copyright = "2015, readthedocs"
6+
author = "readthedocs"
7+
version = "0.1"
8+
release = "0.1"
9+
language = "en"
10+
exclude_patterns = ["_build"]
11+
pygments_style = "sphinx"
12+
todo_include_todos = False
13+
html_theme = "alabaster"
14+
htmlhelp_basename = "pyexampledoc"
15+
extensions = ["sphinx.ext.autodoc", "autoapi.extension"]
16+
autoapi_dirs = ["example"]
17+
autoapi_python_class_content = "both"
18+
autoapi_options = [
19+
"members",
20+
"imported-members",
21+
"inherited-members",
22+
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
def func() -> int:
2+
"""Returns five."""
3+
return 5
4+
5+
6+
class Foo:
7+
"""This is a class."""

tests/python/pynorender/index.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.. pyexample documentation master file, created by
2+
sphinx-quickstart on Fri May 29 13:34:37 2015.
3+
You can adapt this file completely to your liking, but it should at least
4+
contain the root `toctree` directive.
5+
6+
Welcome to pyexample's documentation!
7+
=====================================
8+
9+
.. toctree::
10+
11+
autoapi/index
12+
13+
Contents:
14+
15+
.. toctree::
16+
:maxdepth: 2
17+
18+
19+
Indices and tables
20+
==================
21+
22+
* :ref:`genindex`
23+
* :ref:`modindex`
24+
* :ref:`search`
25+

tests/python/test_pyintegration.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,3 +1195,10 @@ def test_line_number_order(self, parse):
11951195
method_sphinx_docs = example_file.find(id="example.Foo.method_sphinx_docs")
11961196

11971197
assert method_tricky.sourceline < method_sphinx_docs.sourceline
1198+
1199+
1200+
def test_nothing_to_render_raises_warning(builder):
1201+
with pytest.raises(sphinx.errors.SphinxWarning) as exc_info:
1202+
builder("pynorender", warningiserror=True)
1203+
1204+
assert "No modules were rendered" in str(exc_info.value)

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ python =
1919
3.13: py313
2020

2121
[testenv]
22+
usedevelop = True
2223
deps =
2324
beautifulsoup4
2425
pytest

0 commit comments

Comments
 (0)