From: Markus Armbruster <armbru@redhat.com>
To: John Snow <jsnow@redhat.com>
Cc: qemu-devel <qemu-devel@nongnu.org>,
"Peter Xu" <peterx@redhat.com>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Stefan Berger" <stefanb@linux.vnet.ibm.com>,
"Fabiano Rosas" <farosas@suse.de>,
"Hanna Reitz" <hreitz@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Zhao Liu" <zhao1.liu@intel.com>, "Kevin Wolf" <kwolf@redhat.com>,
"Ani Sinha" <anisinha@redhat.com>,
"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
"Jiri Pirko" <jiri@resnulli.us>,
"Alex Williamson" <alex@shazbot.org>,
"Kashyap Chamarthy" <kchamart@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Kostiantyn Kostiuk" <kkostiuk@redhat.com>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
"Michael Roth" <michael.roth@amd.com>,
"Mauro Carvalho Chehab" <mchehab+huawei@kernel.org>,
"Vladimir Sementsov-Ogievskiy" <vsementsov@yandex-team.ru>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
Qemu-block <qemu-block@nongnu.org>,
"Cédric Le Goater" <clg@redhat.com>,
"Stefano Garzarella" <sgarzare@redhat.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Igor Mammedov" <imammedo@redhat.com>,
"Jason Wang" <jasowangio@gmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Eric Blake" <eblake@redhat.com>
Subject: Re: [PATCH 04/14] qapi/parser: enforce doc block section ordering
Date: Tue, 29 Sep 2026 17:00:29 +0200 [thread overview]
Message-ID: <874if8w19u.fsf@pond.sub.org> (raw)
In-Reply-To: <CAFn=p-ZCq09nrc=O7jCay9JJ9c9eopMzQmDqHcdS8j=kWtVa_w@mail.gmail.com> (John Snow's message of "Tue, 29 Sep 2026 10:31:42 -0400")
John Snow <jsnow@redhat.com> writes:
> On Tue, Sep 29, 2026, 8:36 AM Markus Armbruster <armbru@redhat.com> wrote:
>
>> John Snow <jsnow@redhat.com> writes:
>>
>> > Enforce the relative ordering of "Intro", "Members", "Features",
>> > "Errors" and "Returns" sections.
>> >
>> > Signed-off-by: John Snow <jsnow@redhat.com>
>> > ---
>> > docs/devel/qapi-code-gen.rst | 19 +++++++++++------
>> > scripts/qapi/parser.py | 41 ++++++++++++++++++++++++++++++------
>> > 2 files changed, 48 insertions(+), 12 deletions(-)
>> >
>> > diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
>> > index 3ac1c2dae18..29e9c5a3da6 100644
>> > --- a/docs/devel/qapi-code-gen.rst
>> > +++ b/docs/devel/qapi-code-gen.rst
>> > @@ -985,12 +985,19 @@ When documentation is required (see pragma_
>> 'doc-required'), every
>> > definition must have documentation.
>> >
>> > Definition documentation starts with a description naming the
>> > -definition with an optional indented overview (the "intro"),
>> > -:ref:`descriptions <doc-descrip>` of each argument (for commands and
>> > -events), member (for structs and unions), branch (for alternates), or
>> > -value (for enums), :ref:`feature descriptions <doc-feat>` of each
>> > -feature (if any), and finally optional :ref:`tagged sections
>> > -<doc-tagged>`.
>> > +definition with an optional indented overview (the "intro").
>> > +
>> > +The introduction is followed by :ref:`descriptions <doc-descrip>` of
>> > +each argument (for commands and events), member (for structs and
>> > +unions), branch (for alternates), or value (for enums).
>> > +
>> > +:ref:`Tagged sections <doc-tagged>` follow in order: Returns (for
>> > +commands), Errors (for commands), and lastly :ref:`feature
>> > +descriptions <doc-feat>` if applicable.
>>
>> *Some* of the tagged sections do.
>>
>> Does this document still need the concept "tagged section"?
>>
>
> I doubt it does, beyond an explanation of common syntax. Happy to hear
> suggestions...
I'll keep it in mind when I review PATCH 02.
> We could also stand to change some of the method names like "ensure
> untagged section" could become "ensure details", and the like.
Fair!
> tagged vs untagged has become increasingly non-meaningful.
True.
>> > +
>> > +Definition documentation concludes with rST-formatted detail
>> > +paragraphs (including examples, notes, &c), and finally an optional
>> > +"Since" tagged section at the very end.
>> >
>> > .. _doc-descrip:
>> >
>> > diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
>> > index fe284a3f866..94a60a23482 100644
>> > --- a/scripts/qapi/parser.py
>> > +++ b/scripts/qapi/parser.py
>> > @@ -545,6 +545,28 @@ def get_doc(self) -> 'QAPIDoc':
>> > doc.all_sections.append(QAPIDoc.Section(info,
>> QAPIDoc.Kind.INTRO))
>> > line = self.get_doc_indented(doc)
>> > no_more_args = False
>> > + last_ordered_section = QAPIDoc.Kind.INTRO
>> > +
>> > + def _tag_check(this: Union['QAPIDoc.Kind', str]) -> None:
>> > + nonlocal last_ordered_section
>> > + if isinstance(this, str):
>> > + this = QAPIDoc.Kind.from_string(this)
>>
>> Simpler, I think: require a .Kind argument, and do the conversion from
>> string in the one caller that needs it.
>>
>
> You're right.
>
>
>> > +
>> > + if this in (QAPIDoc.Kind.TODO, QAPIDoc.Kind.SINCE,
>> > + QAPIDoc.Kind.DETAILS):
>> > + return
>> > +
>> > + if this.value < last_ordered_section.value:
>> > + raise QAPIParseError(
>> > + self,
>> > + f"'{this}' section cannot appear after "
>> > + f"'{last_ordered_section}' section, please
>> re-order "
>> > + "the sections and adjust phrasing as necessary
>> to "
>> > + "ensure consistent documentation flow between
>> the "
>> > + "source code and the rendered HTML manual"
>> > + )
>>
>> That's a loooong error message. It actually consists of the error
>> proper and advice on how to correct it. Please use
>>
>> "<error>\n<advice>"
>>
>> like we do in expr.py's check_keys(), parser.py's
>> ._validate_doc_line_format(), and schema.py's ._def_definition(). Yes,
>> the embedded newline is a bit of a hack.
>>
>
> ACK.
>
>
>> > +
>> > + last_ordered_section = this
>> >
>> > while line is not None:
>> > # Blank lines
>> > @@ -558,6 +580,7 @@ def get_doc(self) -> 'QAPIDoc':
>> > if doc.has_features:
>> > raise QAPIParseError(
>> > self, "duplicated 'Features:' line")
>> > + _tag_check(QAPIDoc.Kind.FEATURE)
>> > self.accept(False)
>> > line = self.get_doc_line()
>> > while line == '':
>> > @@ -581,6 +604,7 @@ def get_doc(self) -> 'QAPIDoc':
>> > self,
>> > "description of '@%s:' follows a section"
>> > % match.group(1))
>> > + _tag_check(QAPIDoc.Kind.MEMBER)
>> > while (line is not None
>> > and (match :=
>> self._match_at_name_colon(line))):
>> > doc.new_argument(self.info, match.group(1))
>> > @@ -621,6 +645,7 @@ def get_doc(self) -> 'QAPIDoc':
>> > )
>> > raise QAPIParseError(self, emsg)
>> >
>> > + _tag_check(match.group(1))
>>
>> This is the caller that needs it.
>>
>
> Yep.
>
>
>> > doc.new_tagged_section(
>> > self.info,
>> > QAPIDoc.Kind.from_string(match.group(1))
>> > @@ -632,6 +657,7 @@ def get_doc(self) -> 'QAPIDoc':
>> > no_more_args = True
>> > else:
>> > # plain paragraph(s)
>> > + _tag_check(QAPIDoc.Kind.DETAILS)
>> > doc.ensure_untagged_section(self.info)
>> > doc.append_line(line)
>> > line = self.get_doc_paragraph(doc)
>> > @@ -674,14 +700,17 @@ class QAPIDoc:
>> > """
>> >
>> > class Kind(enum.Enum):
>> > - DETAILS = 0
>> > + # The order here is the order in which sections must appear in
>> > + # source code; with the exception of 'TODO' which may appear
>> > + # anywhere but is treated as a comment.
>> > + INTRO = 0
>> > MEMBER = 1
>> > - FEATURE = 2
>> > - RETURNS = 3
>> > - ERRORS = 4
>> > - SINCE = 5
>> > + RETURNS = 2
>> > + ERRORS = 3
>> > + FEATURE = 4
>> > + DETAILS = 5
>> > TODO = 6
>> > - INTRO = 7
>> > + SINCE = 7
>> >
>> > @staticmethod
>> > def from_string(kind: str) -> 'QAPIDoc.Kind':
>>
>> Missing: negative test for the new error.
>>
>
> Yep. If you are overall pleased with this change enough (pending nits),
> I'll add the tests now.
I am!
next prev parent reply other threads:[~2026-09-29 15:01 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 22:36 [PATCH 00/14] qapi: enforce section ordering John Snow
2026-09-28 22:36 ` [PATCH 01/14] qapi: rename "plain" sections to "details" John Snow
2026-09-29 11:49 ` Markus Armbruster
2026-09-29 14:36 ` John Snow
2026-09-28 22:36 ` [PATCH 02/14] docs/qapi-code-gen: expand each section's syntax into a mini-section John Snow
2026-09-28 22:36 ` [PATCH 03/14] qapi: re-order QAPI doc block sections John Snow
2026-09-29 12:10 ` Markus Armbruster
2026-09-29 14:32 ` John Snow
2026-09-28 22:36 ` [PATCH 04/14] qapi/parser: enforce doc block section ordering John Snow
2026-09-29 12:36 ` Markus Armbruster
2026-09-29 14:31 ` John Snow
2026-09-29 15:00 ` Markus Armbruster [this message]
2026-09-28 22:36 ` [PATCH 05/14] qapi: move 'details' sections to the bottom of doc blocks John Snow
2026-10-01 11:14 ` Markus Armbruster
2026-09-28 22:36 ` [PATCH 06/14] qapi/parser: enforce 'details' sections' relative position John Snow
2026-09-28 22:36 ` [PATCH 07/14] qapi: re-order 'since' sections to always be last John Snow
2026-09-28 22:36 ` [PATCH 08/14] qapi/parser: enforce strict positioning for "Since:" section John Snow
2026-09-29 12:53 ` Markus Armbruster
2026-09-29 14:25 ` John Snow
2026-09-29 15:04 ` Markus Armbruster
2026-09-28 22:36 ` [PATCH 09/14] qapi/parser: remove _insert_after_intro() helper John Snow
2026-09-29 13:09 ` Markus Armbruster
2026-09-29 14:19 ` John Snow
2026-09-29 15:08 ` Markus Armbruster
2026-09-28 22:36 ` [PATCH 10/14] qapi/parser: add _append() method John Snow
2026-09-29 13:28 ` Markus Armbruster
2026-09-29 14:14 ` John Snow
2026-09-29 15:09 ` Markus Armbruster
2026-09-28 22:36 ` [PATCH 11/14] qapi/parser: privatize "all_sections" field as "_sections" John Snow
2026-10-02 8:51 ` Markus Armbruster
2026-09-28 22:36 ` [PATCH 12/14] qapi/parser: add _active_section private member John Snow
2026-09-28 22:36 ` [PATCH 13/14] qapi/parser: add new _sections mapping John Snow
2026-10-02 7:24 ` Markus Armbruster
2026-09-28 22:36 ` [PATCH 14/14] qapi/parser: convert single-section properties to getter properties John Snow
2026-10-02 9:44 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=874if8w19u.fsf@pond.sub.org \
--to=armbru@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=alex@shazbot.org \
--cc=anisinha@redhat.com \
--cc=berrange@redhat.com \
--cc=clg@redhat.com \
--cc=eblake@redhat.com \
--cc=farosas@suse.de \
--cc=hreitz@redhat.com \
--cc=imammedo@redhat.com \
--cc=jasowangio@gmail.com \
--cc=jiri@resnulli.us \
--cc=jsnow@redhat.com \
--cc=kchamart@redhat.com \
--cc=kkostiuk@redhat.com \
--cc=kwolf@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=mchehab+huawei@kernel.org \
--cc=michael.roth@amd.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=philmd@oss.qualcomm.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=sgarzare@redhat.com \
--cc=stefanb@linux.vnet.ibm.com \
--cc=stefanha@redhat.com \
--cc=vsementsov@yandex-team.ru \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.