On Mon, Jun 16, 2025 at 7:36 AM Markus Armbruster <arm...@redhat.com> wrote:

> John Snow <js...@redhat.com> writes:
>
> > If we remove the legacy parser, the doc-good.json formatting begins to
>
> "parser"?  You mean docs/sphinx/qapidoc_legacy.py, don't you?
>

Mmm... yes, I'm conflating the purpose of the series (removing the legacy
freeform doc parser) with what necessitated this change (switching to the
new doc *generator*)

Wiggly-brained, wiggly-mouthed.


>
> > fail because the body text is appended directly after the field list
> > entry, which is invalid rST syntax.
>
> We've been running the test suite with the legacy doc generator.
> Unwise; we should've switched to the new one right away.
>

Oops O:-)


>
> > Without this change, we see this error:
> >
> > /home/jsnow/src/qemu/docs/../tests/qapi-schema/doc-good.json:169:
> > WARNING: Field list ends without a blank line; unexpected
> > unindent. [docutils]
>
> The reporting is less than helpful.
>
> > And this intermediate rST source:
> >
> > tests/qapi-schema/doc-good.json:0167 |    :error:
> > tests/qapi-schema/doc-good.json:0168 |    some
> >
> > With this patch applied, we instead generate this source:
> >
> > tests/qapi-schema/doc-good.json:0167 |    :error:
> > tests/qapi-schema/doc-good.json:0168 |        - some
> >
> > which compiles successfully.
>
> Hmm.
>
> As far as I can tell, the problem is lack of indentation[*].
>
> By convention, the contents of an Errors: section is a list.
> docs/devel/qapi-code-gen.rst:
>
>     "Errors" sections should be formatted as an rST list, each entry
>     detailing a relevant error condition.  For example::
>
>      # Errors:
>      #     - If @device does not exist, DeviceNotFound
>      #     - Any other error returns a GenericError.
>
> This test case is the only instance of something else.
>
> It's just a convention, though.
>
> Your change to the positive test case makes some sense all the same; it
> should cover how we want the thing to be used.
>
> What I don't like is how the new doc generator fails when we fail to
> adhere to the convention.
>

I agree... it should probably generate ":error: some" instead, without the
newline. Bad, but valid.


>
> Here's docs/devel/qapi-code-gen.rst on tagged sections:
>
>     A tagged section begins with a paragraph that starts with one of the
>     following words: "Since:", "Returns:", "Errors:", "TODO:".  It ends
> with
>     the start of a new section.
>
>     The second and subsequent lines of tagged sections must be indented
>     like this::
>
>      # TODO: Ut enim ad minim veniam, quis nostrud exercitation ullamco
>      #     laboris nisi ut aliquip ex ea commodo consequat.
>      #
>      #     Duis aute irure dolor in reprehenderit in voluptate velit esse
>      #     cillum dolore eu fugiat nulla pariatur.
>
> This tells us that
>
>     # Errors: some
>
> and
>
>     # Errors:
>     #     some
>
> and
>
>     # Errors: some
>     #     more
>
> should all work, just like for any other tag.  However, only the second
> one works in my testing.  With qapidoc_legacy.py, all three work.
>
> We can make Errors: unlike the other tags.  But it needs to be done
> properly, i.e. in scripts/qapi/parser.py (for decent error reporting),
> and documented in docs/devel/qapi-code-gen.rst.
>
> Keeping the QAPI domain accept what the generator generates might be
> easier.
>
> Thoughts?
>

I try not to have any as often as I can.

In seriousness, I need a good few minutes with the generator to understand
why this behaves strangely. Might need to switch to a different parser
routine in parser.py, or I might need to adjust the qapidoc generator. Not
entirely sure what's precisely wrong... If I can find something that's both
easy and clean I'll do that instead.

Probably a newline needs to be preserved in the source somewhere, and then
a newline needs to be *not* added to the generator. Something like that.

We can discuss turning our de-facto standard into an actual syntactical
requirement later; I think there might be some benefit to allowing multiple
errors sections that each become their own ":error:" info field list entry,
but I am not confident on that and am not ready to dive into it just yet. I
think it's definitely easier on the sphinx side but it might not be easier
on the QAPI side. We'll see...


>
> >
> > Signed-off-by: John Snow <js...@redhat.com>
> > ---
> >  tests/qapi-schema/doc-good.json | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/qapi-schema/doc-good.json
> b/tests/qapi-schema/doc-good.json
> > index 14b808f9090..6dcde8fd7e8 100644
> > --- a/tests/qapi-schema/doc-good.json
> > +++ b/tests/qapi-schema/doc-good.json
> > @@ -165,7 +165,8 @@
> >  #
> >  # Returns: @Object
> >  #
> > -# Errors: some
> > +# Errors:
> > +#     - some
> >  #
> >  # TODO: frobnicate
> >  #
>
> Fails "make check".  Fixup appended.
>

Strange. How'd I find this issue and fix it if I wasn't running the tests?
Uhm, sorry. Sloppy of me.


>
>
>
> [*] Evidence:
>
>     # Errors:
>     #     - some
>
> which expands into
>
>     :error:
>         - some
>
> and
>
>     # Errors:
>     #     some
>
> which expands into
>
>     :error:
>         some
>
> both work.
>
> docs/devel/qapi-domain.rst:
>
>     ``:error:``
>     -----------
>
>     Document the error condition(s) of a QAPI command.
>
>     :availability: This field list is only available in the body of the
>                    Command directive.
> --> :syntax: ``:error: Lorem ipsum dolor sit amet ...``
>     :type: `sphinx.util.docfields.Field
>            <
> https://pydoc.dev/sphinx/latest/sphinx.util.docfields.Field.html?private=1
> >`_
>
>     The format of the :errors: field list description is free-form rST. The
>     alternative spelling ":errors:" is also permitted, but strictly
>     analogous.
>
>     Example::
>
>        .. qapi:command:: block-job-set-speed
>           :since: 1.1
>
>           Set maximum speed for a background block operation.
>
>           This command can only be issued when there is an active block
> job.
>
>           Throttling can be disabled by setting the speed to 0.
>
>           :arg string device: The job identifier.  This used to be a device
>               name (hence the name of the parameter), but since QEMU 2.7 it
>               can have other values.
>           :arg int speed: the maximum speed, in bytes per second, or 0 for
>               unlimited.  Defaults to 0.
> -->       :error:
> -->           - If no background operation is active on this device,
> -->             DeviceNotActive
>
> This makes me expect
>
>     :error: some
>
> also works.  However, the obvious
>
>     # Errors: some
>
> produces
>
>     :error:
>     some
>
> which doesn't work.
>
>
> diff --git a/tests/qapi-schema/doc-good.out
> b/tests/qapi-schema/doc-good.out
> index dc8352eed4..3711cf5480 100644
> --- a/tests/qapi-schema/doc-good.out
> +++ b/tests/qapi-schema/doc-good.out
> @@ -176,7 +176,7 @@ another feature
>      section=Returns
>  @Object
>      section=Errors
> -some
> +    - some
>      section=Todo
>  frobnicate
>      section=Plain
> diff --git a/tests/qapi-schema/doc-good.txt
> b/tests/qapi-schema/doc-good.txt
> index 17a1d56ef1..e54cc95f4a 100644
> --- a/tests/qapi-schema/doc-good.txt
> +++ b/tests/qapi-schema/doc-good.txt
> @@ -207,7 +207,7 @@ Returns
>  Errors
>  ~~~~~~
>
> -some
> +* some
>
>  Notes:
>
>
>

Reply via email to