On Fri, Mar 7, 2025 at 1:59 AM Markus Armbruster <arm...@redhat.com> wrote:
> John Snow <js...@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 <js...@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: > > """ > >