This docstring:
"""
Returns
-------
out: int
Output.
Bad title
---------
Text.
"""
produces:
C:\module.py:docstring of my_pkg.module.func:5: CRITICAL: Unexpected section title.
Bad title
---------
Can I make it respect Bad title
, or at least suppress the warning? I'm not using numpydoc
or Napoleon, only
extensions = ['sphinx.ext.autodoc']
The two related questions with shared "Unexpected etc" don't help.
Built with sphinx-build -a -E . build
. For convenience, here's sphinx-dummy-min.zip.
sphinx-dummy-min/docs/conf.py
import sys, pathlib
sys.path.insert(0, str(pathlib.Path(__file__).parent.parent))
project = 'dummy-module'
release = version = '0.1.0'
extensions = ['sphinx.ext.autodoc']
exclude_patterns = ['build']
sphinx-dummy-min/docs/dummy_module.rst
sphinx-dummy-min package
========================
Submodules
----------
dummy_module.dumdum module
--------------------------
.. automodule:: dummy_module.dumdum
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: dummy_module
:members:
:undoc-members:
:show-inheritance:
sphinx-dummy-min/docs/index.rst
Welcome to dummy-module-min's documentation!
============================================
.. toctree::
:maxdepth: 2
:caption: Contents:
.. toctree::
:maxdepth: 2
:caption: Galleries:
API reference <dummy_module>
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
sphinx-dummy-min/dummy_module/__init__.py
sphinx-dummy-min/dummy_module/dumdum.py
def bark():
"""
Returns
-------
out: str
"Bark".
Bad title
---------
Body.
"""
Arbitrary titles can be supported via 'sphinx.ext.napoleon'
's napoleon_custom_sections
in conf.py
:
napoleon_custom_sections = ['Bad title']
This can be automated by iterating all .py
in the package and finding ----
in docstrings - my approach below.
Note, nested titles will also generate the warning - e.g.
Parameters
----------
param: str
This is a param.
Extended description
--------------------
This is a parameter.
but that's fair enough.
from pathlib import Path
def scrape_titles_in_folder(_dir):
def scrape_titles_in_file(p):
with open(p, 'r') as f:
txt_lines = f.readlines()
titles = []
inside_of_docstring = False
for i, line in enumerate(txt_lines):
if '"""' in line:
inside_of_docstring = not inside_of_docstring
# '---' or shorter is prone to false positives
subsection_symbols = ('-', '^') # can add more
if (inside_of_docstring and
# `3` or less is prone to false positives (e.g. '-')
any(s * 4 in line for s in subsection_symbols)):
contender = txt_lines[i - 1].strip(' \n')
if contender != '': # can appear for some reason
titles.append(contender)
# e.g. """Docstring."""
if line.count('"""') == 2:
inside_of_docstring = not inside_of_docstring
return titles
all_titles = []
for p in _dir.iterdir():
if p.suffix == '.py':
all_titles.extend(scrape_titles_in_file(p))
elif p.is_dir():
all_titles.extend(scrape_titles_in_folder(p))
return list(set(all_titles)) # unique only
module_dir = Path(Path(__file__).parent.parent, 'dummy_module')
section_titles = scrape_titles_in_folder(module_dir)
napoleon_custom_sections = section_titles