New (and I believe much better!) idea for a docstring macro engine, as a use case for the current PEP822 draft (going slightly off tangent here, but bear with me):
Most developers have the DRY (Don’t Repeat Yourself) principle in their backbone, however annoyingly, Python out-of-the-box does not support a way to avoid duplicating content in docstrings. This is, I believe, one of the arguments for the now withdrawn PEP 727 – Documentation in Annotated Metadata | peps.python.org which would have allowed attaching e.g. parameter docs to the actual parameters through the type system. One of my issues with PEP 727 was the cumbersome notation, but I found the idea sound and useful in some, but not all cases. In any case, I believe there is room for an official, but complementary approach to allow DRY for regular docstrings. The lack of such a solution has lately caused me to spend considerable effort to implement my own in-house docstring macro system (where supporting correct indentation was one of the main headaches), which I would be happy to scrap if I had an alternative.
Consider something like this:
- t-strings (template strings) and d-strings are supported for docstrings
- variables to be substituted into docstring templates are defined in a confined way, not fully runtime, e.g. in a module.dpy file (or some other clever way)
- The Python parser or other preprocessor does the template substitution pre-runtime (somehow, somewhere, I don’t know the architecture of CPython)
Then, one could do something like:
mymodule.py:
def my_func(number: int):
dt"""
my_func takes a number and does something with it.
Args:
{number_param}
"""
mymodule.dpy:
number_param = d"""
number (int): a number provided as input. this description is long, so it
needs multiples lines.
"""
For this to really be powerful, template insertion with dedent handling could be supported. This would allow moving the dedenting from the d-string to the insertion, so that one could e.g. write the more user-friendly variant (here following the {-> notation proposed above PEP 822: Dedented Multiline String (d-string) - #36 by hprodh ):
mymodule.py:
def my_func(number: int):
dt"""
my_func takes a number and does something with it.
Args:
{->number_param}
"""
mymodule.dpy:
number_param = d"""
number (int): a number provided as input. this description is long, so it
needs multiples lines.
"""
So my argument in favor of the current PEP as it stands is that a powerful and relatively simple docstring macro engine could be built on top of it with:
- PEP 822 providing a convenient way to:
- define multistring macro content (handling the correct amount of dedenting out-of-the box)
- alternative docstring formatting, with the description line below the “”" line (which looks better to me)
- A new docstring macro PEP would add most of the convenience straight away (complementing PEP 727-like approaches)
- A template substitution with dedenting PEP would provide additional power/usability
Thoughts?