On Fri, Mar 7, 2025 at 1:59 AM Markus Armbruster <armbru@redhat.com> wrote:
> John Snow <jsnow@redhat.com> writes:
>
> > Add a little special markup for registering "Since:" information. Adding
> > it as an option instead of generic content lets us hoist the information
> > into the Signature bar, optionally put it in the index, etc.
> >
> > Signed-off-by: John Snow <jsnow@redhat.com>
> > ---
> > docs/sphinx/qapi_domain.py | 29 +++++++++++++++++++++++++++--
> > 1 file changed, 27 insertions(+), 2 deletions(-)
> >
> > diff --git a/docs/sphinx/qapi_domain.py b/docs/sphinx/qapi_domain.py
> > index 6168c23936f..9919dacd4e6 100644
> > --- a/docs/sphinx/qapi_domain.py
> > +++ b/docs/sphinx/qapi_domain.py
> > @@ -4,6 +4,7 @@
> >
> > from __future__ import annotations
> >
> > +import re
> > from typing import (
> > TYPE_CHECKING,
> > AbstractSet,
> > @@ -104,6 +105,18 @@ def process_link(
> > return title, target
> >
> >
> > +def since_validator(param: str) -> str:
> > + """
> > + Validate the `:since: X.Y` option field.
> > + """
> > + match = re.match(r"[0-9]+\.[0-9]+", param)
>
> This accepts arbitrary crap after the version. Example:
> "9.2.50v9.2.0-2253-ge8a0110293" is fine. Intentional?
>
Nope! O:-) I forgot that match doesn't imply ^...$
>
> > + if not match:
> > + raise ValueError(
> > + f":since: requires a version number in X.Y format; not
> {param!r}"
> > + )
> > + return param
>
> Schema validation is the frontend's job. Ideally, a backend doesn't
> report any errors. The backends generating C don't. A backend
> generating docs has to: all the reST processing happens there, and
> therefore reST errors can only be diagnosed there. Since "no errors"
> purity is impossible for this backend, we can be pragmatic about sinning
> a bit more.
>
> Still, I think this one should rather go into the doc comment parser.
>
> This is not a demand. We can always clean it up later.
>
You *can* technically use this without touching the QAPI parser at all,
nothing stops you. I.e., you *could* write a QMP reference manual by hand
into an .rst if you wanted.
That said, I know we probably won't. I can remove the validator.
>
> > +
> > +
> > # Alias for the return of handle_signature(), which is used in several
> places.
> > # (In the Python domain, this is Tuple[str, str] instead.)
> > Signature = str
> > @@ -124,6 +137,8 @@ class QAPIObject(ObjectDescription[Signature]):
> > {
> > # Borrowed from the Python domain:
> > "module": directives.unchanged, # Override contextual
> module name
> > + # These are QAPI originals:
> > + "since": since_validator,
> > }
> > )
> >
> > @@ -135,9 +150,19 @@ def get_signature_prefix(self) -> List[nodes.Node]:
> > SpaceNode(" "),
> > ]
> >
> > - def get_signature_suffix(self) -> list[nodes.Node]:
> > + def get_signature_suffix(self) -> List[nodes.Node]:
> > """Returns a suffix to put after the object name in the
> signature."""
> > - return []
> > + ret: List[nodes.Node] = []
> > +
> > + if "since" in self.options:
> > + ret += [
> > + SpaceNode(" "),
> > + addnodes.desc_sig_element(
> > + "", f"(Since: {self.options['since']})"
> > + ),
> > + ]
> > +
> > + return ret
> >
> > def handle_signature(self, sig: str, signode: desc_signature) ->
> Signature:
> > """
>
>