All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: John Snow <jsnow@redhat.com>
Cc: 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@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 11/14] qapi/parser: privatize "all_sections" field as "_sections"
Date: Fri, 02 Oct 2026 10:51:01 +0200	[thread overview]
Message-ID: <87pkxs4hai.fsf@pond.sub.org> (raw)
In-Reply-To: <20260928223657.2303684-12-jsnow@redhat.com> (John Snow's message of "Mon, 28 Sep 2026 18:36:54 -0400")

John Snow <jsnow@redhat.com> writes:

> In preparation for switching QAPIDoc to a more complex data structure
> for keeping track of sections, convert the "all_sections" property to
> a private property.

s/property/attribute/

> Rename it "_sections" to emphasize that there is not* some alternative
> property that is somehow not all sections. This is what you get and
> you're going to love it.
>
> Implement the len() and iter() features for QAPIDoc as a replacement
> for direct, public access to the all_sections property.
>
> (*OK, currently there are some, but spoilers, they're going away in
> the next commits.)
>
> Signed-off-by: John Snow <jsnow@redhat.com>

This took a bit of work for me to understand.

I figure "alternative that is somehow not all sections" refers to .args,
._features, ._returns, ._errors, and .since.

You replace the latter three by properties in PATCH 14.  The former two
stay.  "They're going away" is not entirely true.

Or am I confused?

Here'a another way to justify the renaming.  When I added .all_sections
in commit 3d035cd2cca, there was also .sections, which held only the
"sections other than .body, .args, .features".  You dropped .sections in
commit d678c5aff31.  No real need for "all_" since.

> ---
>  docs/sphinx/qapidoc.py         |  7 ++++---
>  scripts/qapi/parser.py         | 27 +++++++++++++++++----------
>  tests/qapi-schema/test-qapi.py |  2 +-
>  3 files changed, 22 insertions(+), 14 deletions(-)
>
> diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
> index ae57056a393..fd666be131f 100644
> --- a/docs/sphinx/qapidoc.py
> +++ b/docs/sphinx/qapidoc.py
> @@ -377,7 +377,7 @@ def visit_sections(self, ent: QAPISchemaDefinition) -> None:
>                  )
>              )
>  
> -        sections = ent.doc.all_sections if ent.doc else []
> +        sections = list(ent.doc) if ent.doc else []

Why listify?  All you need is an iterator as far as I can tell.

>  
>          # Add sections in source order:
>          for section in sections:
> @@ -416,8 +416,9 @@ def visit_module(self, path: str) -> None:
>          self.ensure_blank_line()
>  
>      def visit_freeform(self, doc: QAPIDoc) -> None:
> -        assert len(doc.all_sections) == 1, doc.all_sections
> -        body = doc.all_sections[0]
> +        sections = list(doc)
> +        assert len(sections) == 1, sections
> +        body = sections[0]
>          self.add_lines(self.reformat_arobase(body.text), doc.info)
>          self.ensure_blank_line()

The code here checks "single section", then formats that section.

Works because a free-form doc comment is a single DETAILS section.

Aside: calling it DETAILS is a bit odd, but we'll live.

Aside: if we recognized TODO: there, it could be several, but we don't.
Maybe we should.

Your patch looks fine to me, but I wonder whether we could instead do

           for section in doc:
               assert section.kind == QAPIDoc.Kind.DETAILS
               self.add_lines(self.reformat_arobase(section.text), section.info)
               self.ensure_blank_line()

Separate cleanup patch, I guess.

>  
> diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
> index 0dca1acba4c..bdd0f1ec3ff 100644
> --- a/scripts/qapi/parser.py
> +++ b/scripts/qapi/parser.py
> @@ -19,6 +19,7 @@
>      TYPE_CHECKING,
>      Any,
>      Dict,
> +    Iterator,
>      List,
>      Mapping,
>      Match,
> @@ -758,7 +759,7 @@ def __init__(self, info: QAPISourceInfo, symbol: Optional[str] = None):
>          # definition doc's symbol, None for free-form doc
>          self.symbol: Optional[str] = symbol
>          # the sections in textual order
> -        self.all_sections: List[QAPIDoc.Section] = []
> +        self._sections: List[QAPIDoc.Section] = []
>          # dicts mapping parameter/feature names to their description
>          self._args: Dict[str, QAPIDoc.ArgSection] = {}
>          self._features: Dict[str, QAPIDoc.ArgSection] = {}
> @@ -797,10 +798,16 @@ def _append(self, section: 'QAPIDoc.Section') -> None:
>                  raise QAPISemError(
>                      section.info, "duplicated '%s' section" % section.kind)
>              self.since = section
> -        self.all_sections.append(section)
> +        self._sections.append(section)
> +
> +    def __iter__(self) -> Iterator['QAPIDoc.Section']:
> +        return iter(self._sections)
> +
> +    def __len__(self) -> int:
> +        return len(self._sections)
>  
>      def end(self) -> None:
> -        for section in self.all_sections:
> +        for section in self:
>              section.text = section.text.strip('\n')
>              if (
>                      section.kind not in (
> @@ -813,9 +820,9 @@ def end(self) -> None:
>      def ensure_untagged_section(self, info: QAPISourceInfo) -> None:
>          kind = QAPIDoc.Kind.DETAILS
>  
> -        if self.all_sections and self.all_sections[-1].kind == kind:
> +        if self._sections and self._sections[-1].kind == kind:
>              # extend current section
> -            section = self.all_sections[-1]
> +            section = self._sections[-1]
>              if not section.text:
>                  # Section is empty so far; update info to start *here*.
>                  section.info = info
> @@ -856,7 +863,7 @@ def new_feature(self, info: QAPISourceInfo, name: str) -> None:
>          self._new_description(info, name, QAPIDoc.Kind.FEATURE, self._features)
>  
>      def append_line(self, line: str) -> None:
> -        self.all_sections[-1].append_line(line)
> +        self._sections[-1].append_line(line)
>  
>      def _insert_near_kind(
>          self,
> @@ -865,12 +872,12 @@ def _insert_near_kind(
>          after: bool = False,
>      ) -> bool:
>          """Insert or append a new doc section at a specific point."""
> -        for idx, sect in enumerate(reversed(self.all_sections)):
> +        for idx, sect in enumerate(reversed(list(self))):

Having to listify an iterator just to run it backwards is always sad.
Fortunately, this code is about to go away.

>              if sect.kind == kind:
> -                pos = len(self.all_sections) - idx - 1
> +                pos = len(self) - idx - 1
>                  if after:
>                      pos += 1
> -                self.all_sections.insert(pos, new_sect)
> +                self._sections.insert(pos, new_sect)
>                  return True
>          return False
>  
> @@ -915,7 +922,7 @@ def ensure_returns(self, info: QAPISourceInfo) -> None:
>          # TODO: Take advantage of the new strict section ordering and
>          # simplify this algorithm.
>  
> -        if any(s.kind == QAPIDoc.Kind.RETURNS for s in self.all_sections):
> +        if self._returns:
>              return

Instead of translating the loop, you replace it.  I suspect the loop was
always unnecessary.  Consider a separate commit.

>  
>          # Stub "Returns" section for undocumented returns value
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 5beb96e894f..d5b4ac3a682 100755
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -117,7 +117,7 @@ def test_frontend(fname):
>              print('doc symbol=%s' % doc.symbol)
>          else:
>              print('doc freeform')
> -        for section in doc.all_sections:
> +        for section in doc:
>              if isinstance(section, QAPIDoc.ArgSection):
>                  print('    %s=%s' % (section.kind, section.name))
>              else:



  reply	other threads:[~2026-10-02  8:52 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
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 [this message]
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=87pkxs4hai.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.