Coding 2020-09-23
Sphinx gripes so far:
- Generic classes get their constructor signature given as (*args, **kwargs).
- Type aliases (like other values) get expanded to their underyling value, even if that value is super gnarly.
- No dedicated support for documenting type parameters, a feature that has been in the language for—I'm sorry, but not sorry enough not to say this—five years now. See also the first item.
As you can imagine, these conspired to make documenting a group of generic classes that rely on a generic union referred to via type alias, somewhat unpleasant. I had to approach this from several angles:
From docs/conf.py:
def suppress_all_signatures(
app, what, name, obj, options, signature, return_annotation
):
return ("", "")
def setup(app):
app.connect("autodoc-process-signature", suppress_all_signatures)
From the first module I'm trying to type:
@attr.dataclass(frozen=True, slots=True)
class Repeat(Generic[T_co]):
"""Convert a (presumably finite) stream to a cycle.
Parameters
----------
[T_co] : TypeVar
The yield type of the source iterable, and the instance.
internal : :data:`SizedIterable`\\[T_co]
The underlying Iterable that will be repeated.
"""
The first code block just suppresses all signatures, because most of them run into at least one of the above issues. To replace the (bad) generated signatures, I use parameter documentation in the class docstring. (The docstring is in NumPy format, but I just did that to see what I thought of it.) Before the parameters that actually get passed, I include the type parameters, in square brackets. For now, they get explicitly called out as TypeVars; for working with type variables interesting enough to require documentation, I'll probably need a link to the TypeVar instance documentation in the type section. (Putting the link in the variable name breaks things in a way that implied to me that I should stop pushing my luck. I think I managed to make Napoleon generate invalid ReST.) This isn't all-the-way-baked, since I'm working with a small sample of apparently rather eccentric code.
(Mostly unrelated, but I managed to invalidate some of the tutorials I found, by not having any __init__ methods in the codebase. attrs is just that good. In any case, you can't put documentation into what isn't there.)
Anyway, I should wrap things up, and get back into documenting this stuff tomorrow.
Good night.