
python-doxygen, when Python docstrings meet Doxygen
11 min read
After writing Doxygen filters for Bash and AWK, Python looked as though it ought to be the straightforward one. Python already has documentation syntax, and Doxygen already understands Python, so the space between them appeared smaller than the problems I had solved for Bash and AWK. The interesting part turned out to be that both systems already had established ideas about what Python documentation should look like and how it should be interpreted.
With Bash and AWK, I was introducing documentation structures into languages where Doxygen needed substantial help understanding what I wanted documented. Python was different because it already had docstrings, PEP 257 conventions, type annotations, and established Sphinx/reStructuredText fields. I wanted to preserve that model rather than replace it with Doxygen-specific Python merely because Doxygen happened to be one of the publication targets. That distinction became the organizing principle for python-doxygen: the maintained source should remain ordinary Python, while the translation needed by Doxygen should happen at the Doxygen boundary.
A function could therefore remain documented in a form familiar to Python developers and Python-oriented tooling:
def load(path: str) -> str:
"""Load a value from ``path``.
:param path: Path to load.
:returns: The loaded value.
:raises ValueError: The path is invalid.
"""I did not want developers to maintain a second documentation block beside that docstring or learn a private documentation dialect for this one output format. The source documentation should remain useful to Python linters, IDEs, documentation tools, and anything inspecting __doc__. The problem was therefore less about inventing documentation syntax and more about reconciling the syntax Python already used with the structure Doxygen expected.


