From patchwork Fri Dec 13 01:12:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906267 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 05F00E7717F for ; Fri, 13 Dec 2024 01:18:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFR-0005Vu-5P; Thu, 12 Dec 2024 20:13:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFP-0005Vd-Qd for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:39 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFO-0008Td-8d for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052416; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4VdZDB30eHZhJMRoE6s8/J15E8364oZ3MVURcH7j2XU=; b=QH4nSEpn9hw2jcxjGVjGZ877uF8ALtYhxai4iJU79t1xz8BWUeCSzJbn74zz9ztjQUvtvc OV1pTzUzA/49+3tzcxQK33NLngKfuk+wI8mpli/hWUxptUDxKjLk+TsjrKLReA+zjPVTsJ PItFskM67TIRYEO5iMe2WX8oYpdkZro= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-499-mWHgrHqjO4eGl0L9essZkQ-1; Thu, 12 Dec 2024 20:13:32 -0500 X-MC-Unique: mWHgrHqjO4eGl0L9essZkQ-1 X-Mimecast-MFC-AGG-ID: mWHgrHqjO4eGl0L9essZkQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6DF3619560B8; Fri, 13 Dec 2024 01:13:31 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E53741956086; Fri, 13 Dec 2024 01:13:27 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 01/35] do-not-merge Date: Thu, 12 Dec 2024 20:12:30 -0500 Message-ID: <20241213011307.2942030-2-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: John Snow --- scripts/qapi-lint.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 scripts/qapi-lint.sh diff --git a/scripts/qapi-lint.sh b/scripts/qapi-lint.sh new file mode 100755 index 00000000000..5a8c798001e --- /dev/null +++ b/scripts/qapi-lint.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -e + +if [[ -f qapi/.flake8 ]]; then + echo "flake8 --config=qapi/.flake8 qapi/" + flake8 --config=qapi/.flake8 qapi/ +fi +if [[ -f qapi/pylintrc ]]; then + echo "pylint --rcfile=qapi/pylintrc qapi/" + pylint --rcfile=qapi/pylintrc qapi/ +fi +if [[ -f qapi/mypy.ini ]]; then + echo "mypy --config-file=qapi/mypy.ini qapi/" + mypy --config-file=qapi/mypy.ini qapi/ +fi + +if [[ -f qapi/.isort.cfg ]]; then + pushd qapi + echo "isort -c ." + isort -c . + popd +fi + +if [[ -f ../docs/sphinx/qapi-domain.py ]]; then + files="qapi-domain.py" +fi +if [[ -f ../docs/sphinx/compat.py ]]; then + files="${files} compat.py" +fi +if [[ -f ../docs/sphinx/collapse.py ]]; then + files="${files} collapse.py" +fi + +if [[ -f ../docs/sphinx/qapi-domain.py ]]; then + pushd ../docs/sphinx + + set -x + mypy --strict $files + flake8 --max-line-length=80 $files qapidoc.py + isort -c $files qapidoc.py + black --line-length 80 --check $files qapidoc.py + PYTHONPATH=../scripts/ pylint \ + --rc-file ../../scripts/qapi/pylintrc \ + qapidoc.py + set +x + + popd +fi + +pushd ../build +make -j13 +make check-qapi-schema +make docs +make sphinxdocs +popd From patchwork Fri Dec 13 01:12:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906245 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 65BDDE7717F for ; Fri, 13 Dec 2024 01:14:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFX-0005WN-KF; Thu, 12 Dec 2024 20:13:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFV-0005WC-56 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:45 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFQ-000055-FO for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052419; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=y0QXc60DC0eiI2wYDGoe9/ZjtI8rESFIjBTHClYlcG0=; b=INKrwC+usYxS1ZtYKEGGq2vfOTi5VtACorwiPxuQ8QkXrX8RFdt9/L/bfQKgknPVgr5/D/ Yu8uxWfWdAbeDdBlNAhVtuJMcZdJdFlbAZf6KEJ1hi5Vrg59NqiMVJ/AfkP/OcSBlfABJ5 wRh1WJ0iankz96cbmhghh2rpiuIzKrk= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-148-gs2iGxnaPOWeWfYawqbcIQ-1; Thu, 12 Dec 2024 20:13:35 -0500 X-MC-Unique: gs2iGxnaPOWeWfYawqbcIQ-1 X-Mimecast-MFC-AGG-ID: gs2iGxnaPOWeWfYawqbcIQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9791B1956089; Fri, 13 Dec 2024 01:13:34 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2009C1956086; Fri, 13 Dec 2024 01:13:31 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 02/35] pylint touchups Date: Thu, 12 Dec 2024 20:12:31 -0500 Message-ID: <20241213011307.2942030-3-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: John Snow --- scripts/qapi/pylintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/qapi/pylintrc b/scripts/qapi/pylintrc index c028a1f9f51..c8f8cd22e92 100644 --- a/scripts/qapi/pylintrc +++ b/scripts/qapi/pylintrc @@ -15,6 +15,7 @@ disable=consider-using-f-string, fixme, missing-docstring, too-many-arguments, + too-many-positional-arguments, too-many-branches, too-many-instance-attributes, too-many-statements, From patchwork Fri Dec 13 01:12:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906255 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2D89FE7717F for ; Fri, 13 Dec 2024 01:15:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFa-0005X1-MZ; Thu, 12 Dec 2024 20:13:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFZ-0005Wl-3r for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:49 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFX-00005i-L2 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052426; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hNB7dl3TSLFCZCtDa8noAbO0oY0hQxHlysvc4+Gdxas=; b=gTDEQhvQKVsoe5hGV8KsSOuxKxyw1CUwlFLfo1dCCYGfzA2xGkDLTv2aDn0itZHDTcIN+W mFAd9XgO1RuCuXp2lhmFhHVuYezesGUKYNZiufdCMrrKx8w9Hd5yiysWVf587ELj635LQj oN7/MVD1cEdeR4RhoSg5kR3BQwjawz4= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-314-EdMC53nkPz6D9X3qZ5BD5A-1; Thu, 12 Dec 2024 20:13:40 -0500 X-MC-Unique: EdMC53nkPz6D9X3qZ5BD5A-1 X-Mimecast-MFC-AGG-ID: EdMC53nkPz6D9X3qZ5BD5A Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 83C841956046; Fri, 13 Dec 2024 01:13:39 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7FF6A1956086; Fri, 13 Dec 2024 01:13:35 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 03/35] docs/sphinx: create QAPI domain extension stub Date: Thu, 12 Dec 2024 20:12:32 -0500 Message-ID: <20241213011307.2942030-4-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org It doesn't really do anything yet, we'll get to it brick-by-brick in the forthcoming commits to keep the series breezy and the git history informative. Signed-off-by: John Snow --- docs/conf.py | 9 ++++++- docs/sphinx/qapi-domain.py | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 docs/sphinx/qapi-domain.py diff --git a/docs/conf.py b/docs/conf.py index c11a6ead8a0..f2986ef7d74 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -60,7 +60,14 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['kerneldoc', 'qmp_lexer', 'hxtool', 'depfile', 'qapidoc'] +extensions = [ + 'depfile', + 'hxtool', + 'kerneldoc', + 'qapi-domain', + 'qapidoc', + 'qmp_lexer', +] if sphinx.version_info[:3] > (4, 0, 0): tags.add('sphinx4') diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py new file mode 100644 index 00000000000..293cb922861 --- /dev/null +++ b/docs/sphinx/qapi-domain.py @@ -0,0 +1,52 @@ +""" +QAPI domain extension. +""" + +from __future__ import annotations + +from typing import ( + TYPE_CHECKING, + Any, + Dict, + List, + Tuple, +) + +from sphinx.domains import Domain, ObjType +from sphinx.util import logging + + +if TYPE_CHECKING: + from sphinx.application import Sphinx + +logger = logging.getLogger(__name__) + + +class QAPIDomain(Domain): + """QAPI language domain.""" + + name = "qapi" + label = "QAPI" + + object_types: Dict[str, ObjType] = {} + directives = {} + roles = {} + initial_data: Dict[str, Dict[str, Tuple[Any]]] = {} + indices = [] + + def merge_domaindata( + self, docnames: List[str], otherdata: Dict[str, Any] + ) -> None: + pass + + +def setup(app: Sphinx) -> Dict[str, Any]: + app.setup_extension("sphinx.directives") + app.add_domain(QAPIDomain) + + return { + "version": "1.0", + "env_version": 1, + "parallel_read_safe": True, + "parallel_write_safe": True, + } From patchwork Fri Dec 13 01:12:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906256 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A3369E77180 for ; Fri, 13 Dec 2024 01:16:32 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFc-0005XX-DC; Thu, 12 Dec 2024 20:13:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFZ-0005Wt-RX for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:49 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFY-00005n-9t for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052427; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Aaoavp9ghysemEH6EpP4j7s+yMYaBfsbVbrjE+Krvhk=; b=ZaDQ2rWtokaHtC4BwUZYJv/EZasnFonEtb8UpPrxwjuvnKK/iMCh9Tzli4lZXf3Rfrfskh 7lPv+zD+WrKskof+6n4deBrYddQR0hBX5b8bOfH3hh4EY5ITGamuGS+2T4lsLbDHkGTSUs bTJt3Tc8Rn1fJdSMVifCeE9XZhj5xIA= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-203-Iv4NDcg-MPO5vpxTcj2Odw-1; Thu, 12 Dec 2024 20:13:43 -0500 X-MC-Unique: Iv4NDcg-MPO5vpxTcj2Odw-1 X-Mimecast-MFC-AGG-ID: Iv4NDcg-MPO5vpxTcj2Odw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C2D3F19560AF; Fri, 13 Dec 2024 01:13:42 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 35DC21956086; Fri, 13 Dec 2024 01:13:39 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 04/35] docs/sphinx: add compat.py module and nested_parse helper Date: Thu, 12 Dec 2024 20:12:33 -0500 Message-ID: <20241213011307.2942030-5-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Create a compat module that handles sphinx cross-version compatibility issues. For the inaugural function, add a nested_parse() helper that handles differences in line number tracking for nested directive body parsing. Spoilers: there are more cross-version hacks to come throughout the series. Signed-off-by: John Snow --- docs/sphinx/compat.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/sphinx/compat.py diff --git a/docs/sphinx/compat.py b/docs/sphinx/compat.py new file mode 100644 index 00000000000..4c8d1e94530 --- /dev/null +++ b/docs/sphinx/compat.py @@ -0,0 +1,33 @@ +""" +Sphinx cross-version compatibility goop +""" + +from docutils.nodes import Element + +from sphinx.util.docutils import SphinxDirective, switch_source_input +from sphinx.util.nodes import nested_parse_with_titles + + +def nested_parse(directive: SphinxDirective, content_node: Element) -> None: + """ + This helper preserves error parsing context across sphinx versions. + """ + + # necessary so that the child nodes get the right source/line set + content_node.document = directive.state.document + + try: + # Modern sphinx (6.2.0+) supports proper offsetting for + # nested parse error context management + nested_parse_with_titles( + directive.state, + directive.content, + content_node, + content_offset=directive.content_offset, # type: ignore[call-arg] + ) + except TypeError: + # No content_offset argument. Fall back to SSI method. + with switch_source_input(directive.state, directive.content): + nested_parse_with_titles( + directive.state, directive.content, content_node + ) From patchwork Fri Dec 13 01:12:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906258 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DAB70E7717F for ; Fri, 13 Dec 2024 01:16:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFf-0005Xp-DG; Thu, 12 Dec 2024 20:13:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFd-0005Xe-HD for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:53 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFa-00007g-6U for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:13:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052429; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m/sKnpk4pWfDahNw9QpklkpBz6Dn/PXW1JplulpPypo=; b=fI81zmrIXslucaHkqe0KifmUbFKjx7nasFBz3IaogDn4kfObS2r6g9J7G83BFgbyM+2ZbU rjtTbQO9+Yjn0YKs3BTeV2nahGWxvZdUAFU4wpWr3HZET+tJHJ0qeu6gXhz+imYM9gSr2T DF+pucEifuSCLGrangkDwcMrwjAAWtw= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-644-y5oe0uLtMhifXf8MOyoqVA-1; Thu, 12 Dec 2024 20:13:46 -0500 X-MC-Unique: y5oe0uLtMhifXf8MOyoqVA-1 X-Mimecast-MFC-AGG-ID: y5oe0uLtMhifXf8MOyoqVA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 461371956051; Fri, 13 Dec 2024 01:13:44 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E465D1956086; Fri, 13 Dec 2024 01:13:42 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 05/35] docs/qapi-domain: add qapi:module directive Date: Thu, 12 Dec 2024 20:12:34 -0500 Message-ID: <20241213011307.2942030-6-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This adds a qapi:module directive, which just notes the current module being documented and performs a nested parse of the content block, if present. This code is based pretty heavily on Sphinx's PyModule directive, but with unnecessary features excised. For example: .. qapi:module:: block-core Hello, and welcome to block-core! ================================= lorem ipsum, dolor sit amet ... Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 106 ++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 293cb922861..57b35cf1f53 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -7,21 +7,119 @@ from typing import ( TYPE_CHECKING, Any, + ClassVar, Dict, + Iterable, List, Tuple, + cast, ) +from docutils import nodes +from docutils.parsers.rst import directives + +from compat import nested_parse +from sphinx import addnodes from sphinx.domains import Domain, ObjType from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective +from sphinx.util.nodes import make_id if TYPE_CHECKING: + from docutils.nodes import Element, Node + from sphinx.application import Sphinx + from sphinx.util.typing import OptionSpec logger = logging.getLogger(__name__) +class QAPIModule(SphinxDirective): + """ + Directive to mark description of a new module. + + This directive doesn't generate any special formatting, and is just + a pass-through for the content body. Named section titles are + allowed in the content body. + + Use this directive to associate subsequent definitions with the + module they are defined in for purposes of search and QAPI index + organization. + + :arg: The name of the module. + :opt no-index: Don't add cross-reference targets or index entries. + :opt no-typesetting: Don't render the content body (but preserve any + cross-reference target IDs in the squelched output.) + + Example:: + + .. qapi:module:: block-core + :no-index: + :no-typesetting: + + Lorem ipsum, dolor sit amet ... + + """ + + has_content = True + required_arguments = 1 + optional_arguments = 0 + final_argument_whitespace = False + + option_spec: ClassVar[OptionSpec] = { + # These are universal "Basic" options; + # https://www.sphinx-doc.org/en/master/usage/domains/index.html#basic-markup + "no-index": directives.flag, + "no-typesetting": directives.flag, + "no-contents-entry": directives.flag, # NB: No effect + # Deprecated aliases; to be removed in Sphinx 9.0 + "noindex": directives.flag, + "nocontentsentry": directives.flag, # NB: No effect + } + + def run(self) -> List[Node]: + modname = self.arguments[0].strip() + no_index = "no-index" in self.options or "noindex" in self.options + + self.env.ref_context["qapi:module"] = modname + + content_node: Element = nodes.section() + nested_parse(self, content_node) + + ret: List[Node] = [] + inode = addnodes.index(entries=[]) + + if not no_index: + node_id = make_id(self.env, self.state.document, "module", modname) + target = nodes.target("", "", ids=[node_id], ismod=True) + self.set_source_info(target) + self.state.document.note_explicit_target(target) + + indextext = f"QAPI module; {modname}" + inode = addnodes.index( + entries=[ + ("pair", indextext, node_id, "", None), + ] + ) + ret.append(inode) + content_node.insert(0, target) + + if "no-typesetting" in self.options: + if node_ids := [ + node_id + for el in content_node.findall(nodes.Element) + for node_id in cast(Iterable[str], el.get("ids", ())) + ]: + target = nodes.target(ids=node_ids) + self.set_source_info(target) + ret.append(target) + else: + ret.extend(content_node.children) + + return ret + + class QAPIDomain(Domain): """QAPI language domain.""" @@ -29,7 +127,13 @@ class QAPIDomain(Domain): label = "QAPI" object_types: Dict[str, ObjType] = {} - directives = {} + + # Each of these provides a rST directive, + # e.g. .. qapi:module:: block-core + directives = { + "module": QAPIModule, + } + roles = {} initial_data: Dict[str, Dict[str, Tuple[Any]]] = {} indices = [] From patchwork Fri Dec 13 01:12:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906301 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D8E73E77182 for ; Fri, 13 Dec 2024 01:19:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFs-0005Zt-F7; Thu, 12 Dec 2024 20:14:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFq-0005Z3-C2 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:06 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFg-0000GR-BL for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052433; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m25QGjFSzBPPX2KwzEZ40K5SkrUI42SPbBiq87ZDlhQ=; b=MVYqraj2VEr1iOz/Cp0XUcuM1QKATAoE96DGyiA6MoTefuXF4pCR3t968AcbXKeMb5RcpU H7QB8dWziH7nXM4rwRsRdBbwFonu69B5O7QH+kal1oH943PkeCL22QSIBMkErWSGnimcbY ynsImty9D8VDHJ7enRYNBULt0zIJY+4= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-84-ofDSGHfqMvO3Wqjz7bsCPQ-1; Thu, 12 Dec 2024 20:13:48 -0500 X-MC-Unique: ofDSGHfqMvO3Wqjz7bsCPQ-1 X-Mimecast-MFC-AGG-ID: ofDSGHfqMvO3Wqjz7bsCPQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id DE3561956087; Fri, 13 Dec 2024 01:13:46 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B1AA51956089; Fri, 13 Dec 2024 01:13:44 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 06/35] docs/qapi-domain: add QAPI domain object registry Date: Thu, 12 Dec 2024 20:12:35 -0500 Message-ID: <20241213011307.2942030-7-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This is the first step towards QAPI domain cross-references and a QAPI reference index. For now, just create the object registry and amend the qapi:module directive to use that registry. Update the merge_domaindata method now that we have actual data we may need to merge. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 81 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 57b35cf1f53..76f10b942d7 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -11,6 +11,7 @@ Dict, Iterable, List, + NamedTuple, Tuple, cast, ) @@ -21,6 +22,7 @@ from compat import nested_parse from sphinx import addnodes from sphinx.domains import Domain, ObjType +from sphinx.locale import _, __ from sphinx.util import logging from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_id @@ -35,6 +37,13 @@ logger = logging.getLogger(__name__) +class ObjectEntry(NamedTuple): + docname: str + node_id: str + objtype: str + aliased: bool + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -79,6 +88,7 @@ class QAPIModule(SphinxDirective): } def run(self) -> List[Node]: + domain = cast(QAPIDomain, self.env.get_domain("qapi")) modname = self.arguments[0].strip() no_index = "no-index" in self.options or "noindex" in self.options @@ -91,11 +101,14 @@ def run(self) -> List[Node]: inode = addnodes.index(entries=[]) if not no_index: + # note module to the domain node_id = make_id(self.env, self.state.document, "module", modname) target = nodes.target("", "", ids=[node_id], ismod=True) self.set_source_info(target) self.state.document.note_explicit_target(target) + domain.note_object(modname, "module", node_id, location=target) + indextext = f"QAPI module; {modname}" inode = addnodes.index( entries=[ @@ -126,7 +139,12 @@ class QAPIDomain(Domain): name = "qapi" label = "QAPI" - object_types: Dict[str, ObjType] = {} + # This table associates cross-reference object types (key) with an + # ObjType instance, which defines the valid cross-reference roles + # for each object type. + object_types: Dict[str, ObjType] = { + "module": ObjType(_("module"), "mod", "obj"), + } # Each of these provides a rST directive, # e.g. .. qapi:module:: block-core @@ -135,13 +153,70 @@ class QAPIDomain(Domain): } roles = {} - initial_data: Dict[str, Dict[str, Tuple[Any]]] = {} + + # Moved into the data property at runtime; + # this is the internal index of reference-able objects. + initial_data: Dict[str, Dict[str, Tuple[Any]]] = { + "objects": {}, # fullname -> ObjectEntry + } + indices = [] + @property + def objects(self) -> Dict[str, ObjectEntry]: + ret = self.data.setdefault("objects", {}) + return ret # type: ignore[no-any-return] + + def note_object( + self, + name: str, + objtype: str, + node_id: str, + aliased: bool = False, + location: Any = None, + ) -> None: + """Note a QAPI object for cross reference.""" + if name in self.objects: + other = self.objects[name] + if other.aliased and aliased is False: + # The original definition found. Override it! + pass + elif other.aliased is False and aliased: + # The original definition is already registered. + return + else: + # duplicated + logger.warning( + __( + "duplicate object description of %s, " + "other instance in %s, use :no-index: for one of them" + ), + name, + other.docname, + location=location, + ) + self.objects[name] = ObjectEntry( + self.env.docname, node_id, objtype, aliased + ) + + def clear_doc(self, docname: str) -> None: + for fullname, obj in list(self.objects.items()): + if obj.docname == docname: + del self.objects[fullname] + def merge_domaindata( self, docnames: List[str], otherdata: Dict[str, Any] ) -> None: - pass + for fullname, obj in otherdata["objects"].items(): + if obj.docname in docnames: + # Sphinx's own python domain doesn't appear to bother to + # check for collisions. Assert they don't happen and + # we'll fix it if/when the case arises. + assert fullname not in self.objects, ( + "bug - collision on merge?" + f" {fullname=} {obj=} {self.objects[fullname]=}" + ) + self.objects[fullname] = obj def setup(app: Sphinx) -> Dict[str, Any]: From patchwork Fri Dec 13 01:12:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906246 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8E58BE77182 for ; Fri, 13 Dec 2024 01:14:30 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFp-0005Yp-Uv; Thu, 12 Dec 2024 20:14:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFn-0005YP-UX for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:03 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFf-0000G5-5Y for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052433; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xBuIfzlqNOz/6xZ6DSHAelvGOKi8S/vFA3f21PFplt4=; b=PCMQE3QQLKzXaiFwRvUSUO+XqeSnNaD/VZZJWjaEXzaNb/KDzfEcsF6Mu0K82VzUxnOrKE p0oGcZ26jsXi2JyHt0R+9+zjFDcwIIFhItBy4KJuJ5+seMdpEmp0O1FMyn8fxTWZvBKi6b 8HyLmthlDqTjxUuiSvQ9DRBMuwHlujk= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-170-cezUqv8RNCW4Xxx_u0Ji2Q-1; Thu, 12 Dec 2024 20:13:52 -0500 X-MC-Unique: cezUqv8RNCW4Xxx_u0Ji2Q-1 X-Mimecast-MFC-AGG-ID: cezUqv8RNCW4Xxx_u0Ji2Q Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3100819560A5; Fri, 13 Dec 2024 01:13:51 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 060161956089; Fri, 13 Dec 2024 01:13:48 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 07/35] docs/qapi-domain: add QAPI index Date: Thu, 12 Dec 2024 20:12:36 -0500 Message-ID: <20241213011307.2942030-8-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, T_SPF_TEMPERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Use the QAPI object registry to generate a special index just for QAPI definitions. The index can show entries both by definition type and alphabetically. The index can be linked from anywhere in the QEMU manual by using `qapi-index`. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 74 +++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 76f10b942d7..a83041a0aac 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -12,6 +12,7 @@ Iterable, List, NamedTuple, + Optional, Tuple, cast, ) @@ -21,7 +22,12 @@ from compat import nested_parse from sphinx import addnodes -from sphinx.domains import Domain, ObjType +from sphinx.domains import ( + Domain, + Index, + IndexEntry, + ObjType, +) from sphinx.locale import _, __ from sphinx.util import logging from sphinx.util.docutils import SphinxDirective @@ -52,9 +58,10 @@ class QAPIModule(SphinxDirective): a pass-through for the content body. Named section titles are allowed in the content body. - Use this directive to associate subsequent definitions with the - module they are defined in for purposes of search and QAPI index - organization. + Use this directive to create entries for the QAPI module in the + global index and the qapi index; as well as to associate subsequent + definitions with the module they are defined in for purposes of + search and QAPI index organization. :arg: The name of the module. :opt no-index: Don't add cross-reference targets or index entries. @@ -133,6 +140,60 @@ def run(self) -> List[Node]: return ret +class QAPIIndex(Index): + """ + Index subclass to provide the QAPI definition index. + """ + + name = "index" + localname = _("QAPI Index") + shortname = _("QAPI Index") + + def generate( + self, + docnames: Optional[Iterable[str]] = None, + ) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]: + assert isinstance(self.domain, QAPIDomain) + content: Dict[str, List[IndexEntry]] = {} + collapse = False + + # list of all object (name, ObjectEntry) pairs, sorted by name + # (ignoring the module) + objects = sorted( + self.domain.objects.items(), + key=lambda x: x[0].split(".")[-1].lower(), + ) + + for objname, obj in objects: + if docnames and obj.docname not in docnames: + continue + + # Strip the module name out: + objname = objname.split(".")[-1] + + # Add an alphabetical entry: + entries = content.setdefault(objname[0].upper(), []) + entries.append( + IndexEntry( + objname, 0, obj.docname, obj.node_id, obj.objtype, "", "" + ) + ) + + # Add a categorical entry: + category = obj.objtype.title() + "s" + entries = content.setdefault(category, []) + entries.append( + IndexEntry(objname, 0, obj.docname, obj.node_id, "", "", "") + ) + + # alphabetically sort categories; type names first, ABC entries last. + sorted_content = sorted( + content.items(), + key=lambda x: (len(x[0]) == 1, x[0]), + ) + return sorted_content, collapse + + class QAPIDomain(Domain): """QAPI language domain.""" @@ -160,7 +221,10 @@ class QAPIDomain(Domain): "objects": {}, # fullname -> ObjectEntry } - indices = [] + # Index pages to generate; each entry is an Index class. + indices = [ + QAPIIndex, + ] @property def objects(self) -> Dict[str, ObjectEntry]: From patchwork Fri Dec 13 01:12:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906299 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 548D6E7717F for ; Fri, 13 Dec 2024 01:19:47 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFs-0005a8-K3; Thu, 12 Dec 2024 20:14:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFo-0005YZ-DB for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFj-0000Kv-23 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052438; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PI658TGxm2lg3c756jMgWMre84BQOwaV4cMaqomDZpo=; b=JZqbn/U1bumKHcgv2URaqDQWjora60x5a3pm9h1II63dCFDUoQUDBW9tRk7SEd0s5yT0Jn 0QVWfQZ40+DSDPh5w2EZBUWLTLaagRA679+2jtqFfmPMWGRo/jtf9Cl28rwsix1KLPUDRH uySFhodBmUpOFszMIB5DgklDSNEJoZk= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-673-062IK_IyPTaUv3tyLatcrg-1; Thu, 12 Dec 2024 20:13:54 -0500 X-MC-Unique: 062IK_IyPTaUv3tyLatcrg-1 X-Mimecast-MFC-AGG-ID: 062IK_IyPTaUv3tyLatcrg Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2DAF219560B3; Fri, 13 Dec 2024 01:13:53 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 551C71956086; Fri, 13 Dec 2024 01:13:51 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 08/35] docs/qapi-domain: add resolve_any_xref() Date: Thu, 12 Dec 2024 20:12:37 -0500 Message-ID: <20241213011307.2942030-9-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add the ability to resolve cross-references using the `any` cross-reference syntax. Adding QAPI-specific cross-reference roles will be added in a forthcoming commit, and will share the same find_obj() helper. (There's less code needed for the generic cross-reference resolver, so it comes first in this series.) Once again, this code is based very heavily on sphinx.domains.python. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 94 +++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index a83041a0aac..4928fed3ed9 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -22,6 +22,7 @@ from compat import nested_parse from sphinx import addnodes +from sphinx.addnodes import pending_xref from sphinx.domains import ( Domain, Index, @@ -31,13 +32,15 @@ from sphinx.locale import _, __ from sphinx.util import logging from sphinx.util.docutils import SphinxDirective -from sphinx.util.nodes import make_id +from sphinx.util.nodes import make_id, make_refnode if TYPE_CHECKING: from docutils.nodes import Element, Node from sphinx.application import Sphinx + from sphinx.builders import Builder + from sphinx.environment import BuildEnvironment from sphinx.util.typing import OptionSpec logger = logging.getLogger(__name__) @@ -282,6 +285,95 @@ def merge_domaindata( ) self.objects[fullname] = obj + def find_obj( + self, modname: str, name: str, type: Optional[str] + ) -> list[tuple[str, ObjectEntry]]: + """ + Find a QAPI object for "name", perhaps using the given module. + + Returns a list of (name, object entry) tuples. + + :param modname: The current module context (if any!) + under which we are searching. + :param name: The name of the x-ref to resolve; + may or may not include a leading module. + :param type: The role name of the x-ref we're resolving, if provided. + (This is absent for "any" lookups.) + """ + if not name: + return [] + + names: list[str] = [] + matches: list[tuple[str, ObjectEntry]] = [] + + fullname = name + if "." in fullname: + # We're searching for a fully qualified reference; + # ignore the contextual module. + pass + elif modname: + # We're searching for something from somewhere; + # try searching the current module first. + # e.g. :qapi:cmd:`query-block` or `query-block` is being searched. + fullname = f"{modname}.{name}" + + if type is None: + # type isn't specified, this is a generic xref. + # search *all* qapi-specific object types. + objtypes: Optional[List[str]] = list(self.object_types) + else: + # type is specified and will be a role (e.g. obj, mod, cmd) + # convert this to eligible object types (e.g. command, module) + # using the QAPIDomain.object_types table. + objtypes = self.objtypes_for_role(type) + + # Either we should have been given no type, or the type we were + # given should correspond to at least one real actual object + # type. + assert objtypes + + if name in self.objects and self.objects[name].objtype in objtypes: + names = [name] + elif ( + fullname in self.objects + and self.objects[fullname].objtype in objtypes + ): + names = [fullname] + else: + # exact match wasn't found; e.g. we are searching for + # `query-block` from a different (or no) module. + searchname = "." + name + names = [ + oname + for oname in self.objects + if oname.endswith(searchname) + and self.objects[oname].objtype in objtypes + ] + + matches = [(oname, self.objects[oname]) for oname in names] + if len(matches) > 1: + matches = [m for m in matches if not m[1].aliased] + return matches + + def resolve_any_xref( + self, + env: BuildEnvironment, + fromdocname: str, + builder: Builder, + target: str, + node: pending_xref, + contnode: Element, + ) -> list[tuple[str, Element]]: + results: list[tuple[str, Element]] = [] + matches = self.find_obj(node.get("qapi:module"), target, None) + for name, obj in matches: + role = "qapi:" + self.role_for_objtype(obj.objtype) + refnode = make_refnode( + builder, fromdocname, obj.docname, obj.node_id, contnode, name + ) + results.append((role, refnode)) + return results + def setup(app: Sphinx) -> Dict[str, Any]: app.setup_extension("sphinx.directives") From patchwork Fri Dec 13 01:12:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906265 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 59950E7717F for ; Fri, 13 Dec 2024 01:18:11 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFq-0005Yq-1b; Thu, 12 Dec 2024 20:14:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFo-0005YY-Co for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFj-0000Kx-7k for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052438; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bQZ3m4r2y82cucY6Yi19vRrWkOCJ1oqcIjA0Q4VavPg=; b=i2uHucasbVl1ioy642tL8rpZ1nB3DjRTPiinHfULmL+tGI7LvaA8mT3SruT7LY+L7CTLoT meQ/mO8nXkHWjs/12neU5saGOkgL23xgiUiC0NE1/VxjwbPTDhDMNyrMllAINUxAQjkN54 e9AwcL3HRqc/1b9pZG7KPwwV1axSyYg= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-569-3-4-JDDrNB2nxfbkKYVXiA-1; Thu, 12 Dec 2024 20:13:56 -0500 X-MC-Unique: 3-4-JDDrNB2nxfbkKYVXiA-1 X-Mimecast-MFC-AGG-ID: 3-4-JDDrNB2nxfbkKYVXiA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5247E19560AB; Fri, 13 Dec 2024 01:13:55 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6FD881956086; Fri, 13 Dec 2024 01:13:53 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 09/35] docs/qapi-domain: add QAPI xref roles Date: Thu, 12 Dec 2024 20:12:38 -0500 Message-ID: <20241213011307.2942030-10-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add domain-specific cross-reference syntax. As of this commit, that means new :qapi:mod:`block-core` and :qapi:obj:`block-core` referencing syntax. :mod: will only find modules, but :obj: will find anything registered to the QAPI domain. (In forthcoming commits, this means commands, events, enums, etc.) Creating the cross-references is powered by the QAPIXRefRole class; resolving them is handled by QAPIDomain.resolve_xref(). QAPIXrefRole is copied almost verbatim from Sphinx's own PyXrefRole. PyXrefRole (and QAPIXrefRole) adds two features over the base class: (1) Creating a cross-reference with e.g. :py:class:`~class.name` instructs sphinx to omit the fully qualified parts of the resolved name from the actual link text. This may be useful in the future if we add namespaces to QAPI documentation, e.g. :qapi:cmd:`~qsd.blockdev-backup` could link to the QSD-specific documentation for blockdev-backup while omitting that prefix from the link text. (2) Prefixing the link target with a "." changes the search behavior to prefer locally-scoped items first. I think both of these are worth keeping to help manage future namespace issues between QEMU, QSD and QGA; but it's possible it's extraneous. It may possibly be worth keeping just to keep feature parity with Sphinx's other domains; e.g. "principle of least surprise". Dunno. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 67 +++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 4928fed3ed9..e4f822bbcbd 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -30,6 +30,7 @@ ObjType, ) from sphinx.locale import _, __ +from sphinx.roles import XRefRole from sphinx.util import logging from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_id, make_refnode @@ -53,6 +54,34 @@ class ObjectEntry(NamedTuple): aliased: bool +class QAPIXRefRole(XRefRole): + def process_link( + self, + env: BuildEnvironment, + refnode: Element, + has_explicit_title: bool, + title: str, + target: str, + ) -> tuple[str, str]: + refnode["qapi:module"] = env.ref_context.get("qapi:module") + if not has_explicit_title: + title = title.lstrip(".") # only has a meaning for the target + target = target.lstrip("~") # only has a meaning for the title + # if the first character is a tilde, don't display the module + # parts of the contents + if title[0:1] == "~": + title = title[1:] + dot = title.rfind(".") + if dot != -1: + title = title[dot + 1 :] + # if the first character is a dot, search more specific namespaces first + # else search builtins first + if target[0:1] == ".": + target = target[1:] + refnode["refspecific"] = True + return title, target + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -216,7 +245,13 @@ class QAPIDomain(Domain): "module": QAPIModule, } - roles = {} + # These are all cross-reference roles; e.g. + # :qapi:cmd:`query-block`. The keys correlate to the names used in + # the object_types table values above. + roles = { + "mod": QAPIXRefRole(), + "obj": QAPIXRefRole(), # reference *any* type of QAPI object. + } # Moved into the data property at runtime; # this is the internal index of reference-able objects. @@ -355,6 +390,36 @@ def find_obj( matches = [m for m in matches if not m[1].aliased] return matches + def resolve_xref( + self, + env: BuildEnvironment, + fromdocname: str, + builder: Builder, + type: str, + target: str, + node: pending_xref, + contnode: Element, + ) -> Element | None: + modname = node.get("qapi:module") + matches = self.find_obj(modname, target, type) + multiple_matches = len(matches) > 1 + + if not matches: + return None + elif multiple_matches: + logger.warning( + __("more than one target found for cross-reference %r: %s"), + target, + ", ".join(match[0] for match in matches), + type="ref", + subtype="qapi", + location=node, + ) + name, obj = matches[0] + return make_refnode( + builder, fromdocname, obj.docname, obj.node_id, contnode, name + ) + def resolve_any_xref( self, env: BuildEnvironment, From patchwork Fri Dec 13 01:12:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906300 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BCC7BE7717F for ; Fri, 13 Dec 2024 01:19:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFs-0005Zy-FD; Thu, 12 Dec 2024 20:14:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFq-0005Yr-48 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:06 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFn-0000Nm-NR for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052440; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0/haAsl8udoLAEk0wDJRQc8YiVVCjA7fNnc/ezx9uXA=; b=SmonSoVVOrZXfkdAe12bnl5ygCTEcV2t9W8YK3UV2G6mdHXBxOj7qP+lfsZhIphCW4he4Q n+c4g/FinSJatUFjtYm1R5/ZBXpSPKMPWm6HTYT4QYgV+3hEi2/5c6LeYJP5egXqW/WMwT fTf1SG3w56NkS3ZvRc5xEZdeyz/DfF8= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-41-DUZHDVhXMQeGDUvxnsEZWg-1; Thu, 12 Dec 2024 20:13:59 -0500 X-MC-Unique: DUZHDVhXMQeGDUvxnsEZWg-1 X-Mimecast-MFC-AGG-ID: DUZHDVhXMQeGDUvxnsEZWg Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 30D1A195608B; Fri, 13 Dec 2024 01:13:58 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BFED61956086; Fri, 13 Dec 2024 01:13:55 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 10/35] docs/qapi-domain: add compatibility node classes Date: Thu, 12 Dec 2024 20:12:39 -0500 Message-ID: <20241213011307.2942030-11-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sphinx prior to v4.0 uses different classes for rendering elements of documentation objects; add some compatibility classes to use the right node classes conditionally. Signed-off-by: John Snow --- docs/sphinx/compat.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/compat.py b/docs/sphinx/compat.py index 4c8d1e94530..28cb39161fe 100644 --- a/docs/sphinx/compat.py +++ b/docs/sphinx/compat.py @@ -2,12 +2,27 @@ Sphinx cross-version compatibility goop """ -from docutils.nodes import Element +from typing import Callable +from docutils.nodes import Element, Node, Text + +import sphinx +from sphinx import addnodes from sphinx.util.docutils import SphinxDirective, switch_source_input from sphinx.util.nodes import nested_parse_with_titles +space_node: Callable[[str], Node] +keyword_node: Callable[[str, str], Node] + +if sphinx.version_info[:3] >= (4, 0, 0): + space_node = addnodes.desc_sig_space + keyword_node = addnodes.desc_sig_keyword +else: + space_node = Text + keyword_node = addnodes.desc_annotation + + def nested_parse(directive: SphinxDirective, content_node: Element) -> None: """ This helper preserves error parsing context across sphinx versions. From patchwork Fri Dec 13 01:12:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906253 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E0B03E77180 for ; Fri, 13 Dec 2024 01:15:17 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuFv-0005ak-0q; Thu, 12 Dec 2024 20:14:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFt-0005aQ-AR for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:09 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFr-0000Sq-CX for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052446; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LiK5xtEugF+udTlcuqdL8tZt1K7Z4AIDbXrBiQVqcs0=; b=MfWdjAMShA22HNEot8B2lWSJ7lyikvSjRpG7Ym0urs/lntfbbvom3JJUVoCDj9XFKuVZ0/ /YRumtzGhGWuxM6+UzxDm3nScPdHowpBQzu+yIl6cBp+CoP9BP1NCmKsqWxM000pk+O0QN ZxruU3zkmHjcI6yXctqk3dsMTn8aDq8= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-10-AP7i7sCLO0u3O4R_nraV2g-1; Thu, 12 Dec 2024 20:14:03 -0500 X-MC-Unique: AP7i7sCLO0u3O4R_nraV2g-1 X-Mimecast-MFC-AGG-ID: AP7i7sCLO0u3O4R_nraV2g Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8B77319560A3; Fri, 13 Dec 2024 01:14:02 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 85AAF1956086; Fri, 13 Dec 2024 01:13:58 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 11/35] docs/qapi-domain: add qapi:command directive Date: Thu, 12 Dec 2024 20:12:40 -0500 Message-ID: <20241213011307.2942030-12-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit adds a generic QAPIObject class for use in documenting various QAPI entities in the Sphinx ecosystem. It also adds a stubbed version of QAPICommand that utilizes the QAPIObject class; along with the qapi:command directive, the :qapi:cmd: cross-reference role, and the "command" object type in the QAPI object registry. They don't do anything *particularly* interesting yet, but that will come in forthcoming commits. Note: some versions of mypy get a little confused over the difference between class and instance variables; because sphinx's ObjectDescription does not declare option_spec as a ClassVar (even though it's obvious that it is), mypy may produce this error: qapi-domain.py:125: error: Cannot override instance variable (previously declared on base class "ObjectDescription") with class variable [misc] I can't control that; so silence the error with a pragma. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 144 ++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index e4f822bbcbd..dd4e218a1a0 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -20,9 +20,10 @@ from docutils import nodes from docutils.parsers.rst import directives -from compat import nested_parse +from compat import keyword_node, nested_parse, space_node from sphinx import addnodes -from sphinx.addnodes import pending_xref +from sphinx.addnodes import desc_signature, pending_xref +from sphinx.directives import ObjectDescription from sphinx.domains import ( Domain, Index, @@ -82,6 +83,142 @@ def process_link( return title, target +# 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 + + +class QAPIObject(ObjectDescription[Signature]): + """ + Description of a generic QAPI object. + + It's not used directly, but is instead subclassed by specific directives. + """ + + # Inherit some standard options from Sphinx's ObjectDescription + option_spec: OptionSpec = ( # type:ignore[misc] + ObjectDescription.option_spec.copy() + ) + option_spec.update( + { + # Borrowed from the Python domain: + "module": directives.unchanged, # Override contextual module name + } + ) + + def get_signature_prefix(self, sig: str) -> List[nodes.Node]: + """Returns a prefix to put before the object name in the signature.""" + assert self.objtype + return [ + keyword_node("", self.objtype.title()), + space_node(" "), + ] + + def get_signature_suffix(self, sig: str) -> list[nodes.Node]: + """Returns a suffix to put after the object name in the signature.""" + return [] + + def handle_signature(self, sig: str, signode: desc_signature) -> Signature: + """ + Transform a QAPI definition name into RST nodes. + + This method was originally intended for handling function + signatures. In the QAPI domain, however, we only pass the + definition name as the directive argument and handle everything + else in the content body with field lists. + + As such, the only argument here is "sig", which is just the QAPI + definition name. + """ + modname = self.options.get( + "module", self.env.ref_context.get("qapi:module") + ) + + signode["fullname"] = sig + signode["module"] = modname + sig_prefix = self.get_signature_prefix(sig) + if sig_prefix: + signode += addnodes.desc_annotation( + str(sig_prefix), "", *sig_prefix + ) + signode += addnodes.desc_name(sig, sig) + signode += self.get_signature_suffix(sig) + + return sig + + def _object_hierarchy_parts( + self, sig_node: desc_signature + ) -> Tuple[str, ...]: + if "fullname" not in sig_node: + return () + modname = sig_node.get("module") + fullname = sig_node["fullname"] + + if modname: + return (modname, *fullname.split(".")) + else: + return tuple(fullname.split(".")) + + def get_index_text(self, modname: str, name: Signature) -> str: + """Return the text for the index entry of the object.""" + # NB this is used for the global index, not the QAPI index. + return f"{name} (QMP {self.objtype})" + + def add_target_and_index( + self, name: Signature, sig: str, signode: desc_signature + ) -> None: + # Called by ObjectDescription.run with the result of + # handle_signature; name is the return value of handle_signature + # where sig is the original argument to handle_signature. In our + # case, they're the same for now. + assert self.objtype + + modname = self.options.get( + "module", self.env.ref_context.get("qapi:module") + ) + # Here, sphinx decides to prepend the module name. OK. + fullname = (modname + "." if modname else "") + name + node_id = make_id(self.env, self.state.document, "", fullname) + signode["ids"].append(node_id) + self.state.document.note_explicit_target(signode) + + domain = cast(QAPIDomain, self.env.get_domain("qapi")) + domain.note_object(fullname, self.objtype, node_id, location=signode) + + if "no-index-entry" not in self.options: + indextext = self.get_index_text(modname, name) + assert self.indexnode is not None + if indextext: + self.indexnode["entries"].append( + ("single", indextext, node_id, "", None) + ) + + def _toc_entry_name(self, sig_node: desc_signature) -> str: + # This controls the name in the TOC and on the sidebar. + + # This is the return type of _object_hierarchy_parts(). + toc_parts = cast(Tuple[str, ...], sig_node.get("_toc_parts", ())) + if not toc_parts: + return "" + + config = self.env.app.config + *parents, name = toc_parts + if config.toc_object_entries_show_parents == "domain": + return sig_node.get("fullname", name) + if config.toc_object_entries_show_parents == "hide": + return name + if config.toc_object_entries_show_parents == "all": + return ".".join(parents + [name]) + return "" + + +class QAPICommand(QAPIObject): + """Description of a QAPI Command.""" + + # Nothing unique for now! Changed in later commits O:-) + pass + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -237,12 +374,14 @@ class QAPIDomain(Domain): # for each object type. object_types: Dict[str, ObjType] = { "module": ObjType(_("module"), "mod", "obj"), + "command": ObjType(_("command"), "cmd", "obj"), } # Each of these provides a rST directive, # e.g. .. qapi:module:: block-core directives = { "module": QAPIModule, + "command": QAPICommand, } # These are all cross-reference roles; e.g. @@ -250,6 +389,7 @@ class QAPIDomain(Domain): # the object_types table values above. roles = { "mod": QAPIXRefRole(), + "cmd": QAPIXRefRole(), "obj": QAPIXRefRole(), # reference *any* type of QAPI object. } From patchwork Fri Dec 13 01:12:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906261 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D075DE7717F for ; Fri, 13 Dec 2024 01:16:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuG0-0005bN-7w; Thu, 12 Dec 2024 20:14:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFy-0005bD-MC for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:14 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFx-0000ax-8l for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052452; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m002wEHjt34wmmf8tuiB51lCnoVpWPUUxPt3b8N6FbE=; b=dTkfjBvIeXbEWDKYDF0n05VrRk2+tLzZC4zNfmmjjBgyy1h2k9AJ0xDmiUYrYcWpRzSlev CKNdCkOeMptp5wYN+y4T+HC3s0G2R8SqImf52mEa19nbcQsJSoYvxFuf4TZE1bMil0MjpB M7LHjQXFEFIvlOKEo5GgqXLMZYvOolo= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-614-k3iOu0f4OgCYZAsiHK-FBQ-1; Thu, 12 Dec 2024 20:14:08 -0500 X-MC-Unique: k3iOu0f4OgCYZAsiHK-FBQ-1 X-Mimecast-MFC-AGG-ID: k3iOu0f4OgCYZAsiHK-FBQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 12B9019560B8; Fri, 13 Dec 2024 01:14:07 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D3C131956086; Fri, 13 Dec 2024 01:14:02 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 12/35] docs/qapi-domain: add :since: directive option Date: Thu, 12 Dec 2024 20:12:41 -0500 Message-ID: <20241213011307.2942030-13-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 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 --- 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 dd4e218a1a0..f525579661b 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, Any, @@ -83,6 +84,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) + if not match: + raise ValueError( + f":since: requires a version number in X.Y format; not {param!r}" + ) + return param + + # 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 @@ -103,6 +116,8 @@ class QAPIObject(ObjectDescription[Signature]): { # Borrowed from the Python domain: "module": directives.unchanged, # Override contextual module name + # These are QAPI originals: + "since": since_validator, } ) @@ -114,9 +129,19 @@ def get_signature_prefix(self, sig: str) -> List[nodes.Node]: space_node(" "), ] - def get_signature_suffix(self, sig: str) -> list[nodes.Node]: + def get_signature_suffix(self, sig: str) -> 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 += [ + space_node(" "), + addnodes.desc_sig_element( + "", f"(Since: {self.options['since']})" + ), + ] + + return ret def handle_signature(self, sig: str, signode: desc_signature) -> Signature: """ From patchwork Fri Dec 13 01:12:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906257 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6EF9CE7717F for ; Fri, 13 Dec 2024 01:16:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuG3-0005lW-BR; Thu, 12 Dec 2024 20:14:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuG0-0005bL-2X for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:16 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuFy-0000bG-Kr for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052453; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wx9G0AY9Fsp3e2AflA94nNknerQd2UMco4NcmkG6NBo=; b=YZq+Dmx5Ie9fx/UOJ9ArWuCAoQHyC7vWfVFXw0Cs421xchBc3leW7b0krpQyd/pQudlrP0 PsQdH8099y6RD1wejbXYyuInyqdfNCYZUGFyocNkD50B4i4u99GSpKk1GccPUqKz/jJNAh NYyO98gZeW9a7pzDgXNcNHpXjjBH4y0= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-195-cPdM_cdwNwy-IJqWGBMOCA-1; Thu, 12 Dec 2024 20:14:09 -0500 X-MC-Unique: cPdM_cdwNwy-IJqWGBMOCA-1 X-Mimecast-MFC-AGG-ID: cPdM_cdwNwy-IJqWGBMOCA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CA0511955F40; Fri, 13 Dec 2024 01:14:08 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 54C4A1956086; Fri, 13 Dec 2024 01:14:07 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 13/35] docs/qapi-domain: add "Arguments:" field lists Date: Thu, 12 Dec 2024 20:12:42 -0500 Message-ID: <20241213011307.2942030-14-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This adds special rendering for Sphinx's typed field lists. This patch does not add any QAPI-aware markup, rendering, or cross-referencing for the type names, yet. That feature requires a subclass to TypedField which will happen in its own commit quite a bit later in this series; after all the basic fields and objects have been established first. The syntax for this field is: :arg type name: description description cont'd You can omit the type or the description, but you cannot omit the name -- if you do so, it degenerates into a "normal field list" entry, and probably isn't what you want. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index f525579661b..15a615d8adb 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -34,6 +34,7 @@ from sphinx.locale import _, __ from sphinx.roles import XRefRole from sphinx.util import logging +from sphinx.util.docfields import TypedField from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_id, make_refnode @@ -240,8 +241,18 @@ def _toc_entry_name(self, sig_node: desc_signature) -> str: class QAPICommand(QAPIObject): """Description of a QAPI Command.""" - # Nothing unique for now! Changed in later commits O:-) - pass + doc_field_types = QAPIObject.doc_field_types.copy() + doc_field_types.extend( + [ + # :arg TypeName ArgName: descr + TypedField( + "argument", + label=_("Arguments"), + names=("arg",), + can_collapse=False, + ), + ] + ) class QAPIModule(SphinxDirective): From patchwork Fri Dec 13 01:12:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906296 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 402A8E77180 for ; Fri, 13 Dec 2024 01:19:37 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGD-0005uC-OV; Thu, 12 Dec 2024 20:14:29 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuG9-0005tT-Ee for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:25 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuG3-0000eG-4j for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052457; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+UQTiLGXqIWSEzCIAZ1iFQL8e/U6Oks1NAbc4rk+beo=; b=EIvLESF1B9G5H/0CM/2GSYR0AeiBdBbwmjATDL7rhbRuG/iCYtwMdI6tpxRjKMSaUutN/z i0PO6agq9EQLS52m7ekZ0bZ7n1QYDgmxSdR1oTKC4QqMgJBOiOyo6lxWlb5CPWvrnVDR2+ KKikBYnC5ZPQUyXgi+Sjgv2oaGhL4SQ= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-287-c9Gca_zZMzewS6Cn_i3rnQ-1; Thu, 12 Dec 2024 20:14:11 -0500 X-MC-Unique: c9Gca_zZMzewS6Cn_i3rnQ-1 X-Mimecast-MFC-AGG-ID: c9Gca_zZMzewS6Cn_i3rnQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F31A11955F42; Fri, 13 Dec 2024 01:14:10 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2BFE91956086; Fri, 13 Dec 2024 01:14:09 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 14/35] docs/qapi-domain: add "Features:" field lists Date: Thu, 12 Dec 2024 20:12:43 -0500 Message-ID: <20241213011307.2942030-15-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add support for Features field lists. There is no QAPI-specific functionality here, but this could be changed if desired (if we wanted the feature names to link somewhere, for instance.) This feature list doesn't have any restrictions, so it can be used to document object-wide features or per-member features as deemed appropriate. It's essentially free-form text. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 15a615d8adb..9b83262a0c6 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -34,7 +34,7 @@ from sphinx.locale import _, __ from sphinx.roles import XRefRole from sphinx.util import logging -from sphinx.util.docfields import TypedField +from sphinx.util.docfields import GroupedField, TypedField from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_id, make_refnode @@ -122,6 +122,16 @@ class QAPIObject(ObjectDescription[Signature]): } ) + doc_field_types = [ + # :feat name: descr + GroupedField( + "feature", + label=_("Features"), + names=("feat",), + can_collapse=False, + ), + ] + def get_signature_prefix(self, sig: str) -> List[nodes.Node]: """Returns a prefix to put before the object name in the signature.""" assert self.objtype From patchwork Fri Dec 13 01:12:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906248 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5F6ABE77180 for ; Fri, 13 Dec 2024 01:14:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGF-0005zQ-Tg; Thu, 12 Dec 2024 20:14:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGA-0005th-Q8 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:27 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuG7-0000ef-TJ for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052463; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QPdepso8xSmP8leeknmWo8NzlmVarvknHnZdmjkDCPM=; b=d5Xzlm2ISEyg+UcKxQdSLbaDBlV4RPrPIuvD6aQa0vnadDbo8yhVc71vbvbcqayOD/kNFa YuZ2EN6IoRVCmCq5n/zVI5fm1CsIH6bBiQFg0ibBiN1IWBPijvb1+F05YKuioRCDGfDcBW ZPEfh6CGbZe1VQGpH4Cw2k6MvRE9Kr0= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-329-LvusOLgfNxi7H7kPVEnUTA-1; Thu, 12 Dec 2024 20:14:16 -0500 X-MC-Unique: LvusOLgfNxi7H7kPVEnUTA-1 X-Mimecast-MFC-AGG-ID: LvusOLgfNxi7H7kPVEnUTA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 93E5E195604F; Fri, 13 Dec 2024 01:14:15 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 58D931956086; Fri, 13 Dec 2024 01:14:11 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 15/35] docs/qapi-domain: add "Errors:" field lists Date: Thu, 12 Dec 2024 20:12:44 -0500 Message-ID: <20241213011307.2942030-16-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org ``:error: descr`` can now be used to document error conditions, naming the type of error object and a description of when the error is surfaced. Like the previous Arguments patch, this patch does not apply any special QAPI syntax highlighting or cross-referencing for the types, but this can be adjusted in the future if desired. (At present, I have no commits that add such highlighting. Sphinx also does not appear to support Grouped fields with optional (or no) parameters, so the ability to exclude error types is currently not supported. If you omit the type, Sphinx treats it as a regular field list and doesn't apply the special Grouping postprocessing to it.) Signed-off-by: John Snow qapi-domain fixup - Error field Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 9b83262a0c6..4bfc82aafdf 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -34,7 +34,7 @@ from sphinx.locale import _, __ from sphinx.roles import XRefRole from sphinx.util import logging -from sphinx.util.docfields import GroupedField, TypedField +from sphinx.util.docfields import Field, GroupedField, TypedField from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_id, make_refnode @@ -261,6 +261,13 @@ class QAPICommand(QAPIObject): names=("arg",), can_collapse=False, ), + # :error: descr + Field( + "error", + label=_("Errors"), + names=("error", "errors"), + has_arg=False, + ), ] ) From patchwork Fri Dec 13 01:12:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906266 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 07278E77180 for ; Fri, 13 Dec 2024 01:18:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGG-00060T-AQ; Thu, 12 Dec 2024 20:14:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGB-0005tm-UR for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:28 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGA-0000ed-2w for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UzHNygLXVObLJFRUedomApYOH0eIg84xgMKEVnWctDs=; b=R4cjiueGa071Ph3pOjSx17iZXzlP7K+bRQZudfZytttKiHG1o2Lq9prbunXWi+sCPM5ZC2 tGsYOzW4aZeHtdoaXZKynkmeRCM8i55prAaHLSeL0Z+sFs2S+pA2u3LsbkgcTlimGRet/G npxejiNNLDFAPc3dOepX+P0qIWBTyzM= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-495-hhjiugPQN0WED5UGZNSoyw-1; Thu, 12 Dec 2024 20:14:20 -0500 X-MC-Unique: hhjiugPQN0WED5UGZNSoyw-1 X-Mimecast-MFC-AGG-ID: hhjiugPQN0WED5UGZNSoyw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 808181955F43; Fri, 13 Dec 2024 01:14:19 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D4030195609D; Fri, 13 Dec 2024 01:14:15 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 16/35] docs/qapi-domain: add "Returns:" field lists Date: Thu, 12 Dec 2024 20:12:45 -0500 Message-ID: <20241213011307.2942030-17-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add "Returns:" field list syntax to QAPI Commands. Like "Arguments:" and "Errors:", the type name isn't currently processed for cross-referencing, but this will be addressed in a forthcoming commit. This patch adds "errors" as a GroupedField, which means that multiple return values can be annotated - this is only done because Sphinx does not seemingly (Maybe I missed it?) support mandatory type arguments to Ungrouped fields. Because we want to cross-reference this type information later, we want to make the type argument mandatory. As a result, you can technically add multiple :return: fields, though I'm not aware of any circumstance in which you'd need or want to. Recommendation: "Don't do that, then." Since this field describes an action/event instead of describing a list of nouns (arguments, features, errors), I added both the imperative and indicative forms (:return: and :returns:) to allow doc writers to use whichever mood "feels right" in the source document. The rendered output will always use the "Returns:" label, however. I'm sure you'll let me know how you feel about that. O:-) Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 4bfc82aafdf..c8c8ffc0dce 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -268,6 +268,13 @@ class QAPICommand(QAPIObject): names=("error", "errors"), has_arg=False, ), + # :returns TypeName: descr + GroupedField( + "returnvalue", + label=_("Returns"), + names=("return", "returns"), + can_collapse=True, + ), ] ) From patchwork Fri Dec 13 01:12:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906249 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A8851E77180 for ; Fri, 13 Dec 2024 01:15:05 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGJ-00063q-E9; Thu, 12 Dec 2024 20:14:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGD-0005yC-TW for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:30 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGB-0000ey-Mf for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052466; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xQSRk5rVnXkv2Ir8hXt5mWcFR2B4kKiqbhFHdu0NBDo=; b=IYrABrwGPIARRN/AExdzTd1/fpXjJ2dbR13Y/jKHdiPPIPzg5/MpQ+BIrigrlVSb9cFeXq EC+7vjmIdiW+jf7EuwFm07KeubzZF4UTJ8FABFDqc0OyBrgKPh+k3kdaE8PJYgnOzi1DE7 UJrrYkM7IiVQGZ9uRMSP4kg5IWRD1D8= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-340-SZEspY-7Nxam9dVZerkaJQ-1; Thu, 12 Dec 2024 20:14:23 -0500 X-MC-Unique: SZEspY-7Nxam9dVZerkaJQ-1 X-Mimecast-MFC-AGG-ID: SZEspY-7Nxam9dVZerkaJQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EF91B19560B2; Fri, 13 Dec 2024 01:14:21 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C6D5E1956086; Fri, 13 Dec 2024 01:14:19 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 17/35] docs/qapi-domain: add returns-nodesc Date: Thu, 12 Dec 2024 20:12:46 -0500 Message-ID: <20241213011307.2942030-18-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This form is used to annotate a return type without an accompanying description, for when there is no "Returns:" information in the source doc, but we have a return type we want to generate a cross-reference to. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index c8c8ffc0dce..c46c87168bd 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -275,6 +275,14 @@ class QAPICommand(QAPIObject): names=("return", "returns"), can_collapse=True, ), + # :returns-nodesc: TypeName + Field( + "returnvalue", + label=_("Returns"), + names=("returns-nodesc",), + bodyrolename="type", + has_arg=False, + ), ] ) From patchwork Fri Dec 13 01:12:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906271 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8F05FE7717F for ; Fri, 13 Dec 2024 01:18:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGT-0006Vk-RC; Thu, 12 Dec 2024 20:14:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGI-00068a-WD for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:35 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGF-0000fw-KP for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052470; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Uelnq1KNF+xgRsYXr6SFESLtd2hWdEYOYf8k2zY/hTI=; b=I7yEmepTLuTYbM/1+Tvh8Ha6eEerMaqla4+D/CyI/6MwiFBXOp/d6Xbtkj2dH5R3DpTR1l kOoMl3EsvxEvCqQKhnew5HbpjKxcNGWnUdu18iRP54fUuz1M1O45bFtEmW6MdfX5AVwMOb AtPCqjFSJEbiamoQn5SyaxG8Y/hihYw= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-494--XK2qujlP2CEpHExN2Wr3A-1; Thu, 12 Dec 2024 20:14:26 -0500 X-MC-Unique: -XK2qujlP2CEpHExN2Wr3A-1 X-Mimecast-MFC-AGG-ID: -XK2qujlP2CEpHExN2Wr3A Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4E54519560B2; Fri, 13 Dec 2024 01:14:25 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 30FE31956086; Fri, 13 Dec 2024 01:14:22 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 18/35] docs/qapi-domain: add qapi:enum directive Date: Thu, 12 Dec 2024 20:12:47 -0500 Message-ID: <20241213011307.2942030-19-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add the .. qapi:enum:: directive, object, and :qapi:enum:`name` cross-reference role. Add the :value name: field list for documenting Enum values. Of note, also introduce a new "type" role that is intended to be used by other QAPI object directives to cross-reference arbitrary QAPI type names, but will exclude commands, events, and modules from consideration. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index c46c87168bd..e37e300e4e6 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -287,6 +287,23 @@ class QAPICommand(QAPIObject): ) +class QAPIEnum(QAPIObject): + """Description of a QAPI Enum.""" + + doc_field_types = QAPIObject.doc_field_types.copy() + doc_field_types.extend( + [ + # :value name: descr + GroupedField( + "value", + label=_("Values"), + names=("value",), + can_collapse=False, + ) + ] + ) + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -440,9 +457,14 @@ class QAPIDomain(Domain): # This table associates cross-reference object types (key) with an # ObjType instance, which defines the valid cross-reference roles # for each object type. + # + # e.g., the :qapi:type: cross-reference role can refer to enum, + # struct, union, or alternate objects; but :qapi:obj: can refer to + # anything. Each object also gets its own targeted cross-reference role. object_types: Dict[str, ObjType] = { "module": ObjType(_("module"), "mod", "obj"), "command": ObjType(_("command"), "cmd", "obj"), + "enum": ObjType(_("enum"), "enum", "obj", "type"), } # Each of these provides a rST directive, @@ -450,6 +472,7 @@ class QAPIDomain(Domain): directives = { "module": QAPIModule, "command": QAPICommand, + "enum": QAPIEnum, } # These are all cross-reference roles; e.g. @@ -458,6 +481,9 @@ class QAPIDomain(Domain): roles = { "mod": QAPIXRefRole(), "cmd": QAPIXRefRole(), + "enum": QAPIXRefRole(), + # reference any data type (excludes modules, commands, events) + "type": QAPIXRefRole(), "obj": QAPIXRefRole(), # reference *any* type of QAPI object. } From patchwork Fri Dec 13 01:12:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906250 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 67378E77182 for ; Fri, 13 Dec 2024 01:15:07 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGS-0006Rg-CF; Thu, 12 Dec 2024 20:14:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGJ-00068b-0p for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:35 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGG-0000ft-Tk for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052470; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gPT+u3LXxfH0gjTJDFgoPLbgfnZcJHf1GRuIQEBj2Kk=; b=fIUsBlQHtCRwoRsn7wrGBq1NhmfEu3yFd2/vwBBB4IuozFXhhbbKFsolAupQ19P6yKbKh1 FiE/DMoosc04Bz9EagbQtB7NDYqZs4//oo5tPX6WOOIQF/aJ16X5q+54yS+FA7hluQTyyn luKt3dNh9UQioTN1bbcTWTe15XyAX+8= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-388-NCSidw38P52JEilwYHPknw-1; Thu, 12 Dec 2024 20:14:28 -0500 X-MC-Unique: NCSidw38P52JEilwYHPknw-1 X-Mimecast-MFC-AGG-ID: NCSidw38P52JEilwYHPknw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CBDED195609F; Fri, 13 Dec 2024 01:14:27 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A74421956086; Fri, 13 Dec 2024 01:14:25 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 19/35] docs/qapi-domain: add qapi:alternate directive Date: Thu, 12 Dec 2024 20:12:48 -0500 Message-ID: <20241213011307.2942030-20-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add the .. qapi:alternate:: directive, object, and qapi:alt:`name` cross-reference role. Add the "Choices:" field list for describing alternate choices. Like other field lists that reference QAPI types, a forthcoming commit will add cross-referencing support to this field. RFC: In the future, it would be nice to directly inline Alternates as part of the type information in the containing object (i.e. directly in arguments/members) - but that's a task for another series. For now, the branch "names" are documented just like qapidoc.py does, even though this information is superfluous for user documentation. Room for future improvement, but not now. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index e37e300e4e6..e0c31b2ee4d 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -304,6 +304,23 @@ class QAPIEnum(QAPIObject): ) +class QAPIAlternate(QAPIObject): + """Description of a QAPI Alternate.""" + + doc_field_types = QAPIObject.doc_field_types.copy() + doc_field_types.extend( + [ + # :choice type name: descr + TypedField( + "choice", + label=_("Choices"), + names=("choice",), + can_collapse=False, + ), + ] + ) + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -465,6 +482,7 @@ class QAPIDomain(Domain): "module": ObjType(_("module"), "mod", "obj"), "command": ObjType(_("command"), "cmd", "obj"), "enum": ObjType(_("enum"), "enum", "obj", "type"), + "alternate": ObjType(_("alternate"), "alt", "obj", "type"), } # Each of these provides a rST directive, @@ -473,6 +491,7 @@ class QAPIDomain(Domain): "module": QAPIModule, "command": QAPICommand, "enum": QAPIEnum, + "alternate": QAPIAlternate, } # These are all cross-reference roles; e.g. @@ -482,6 +501,7 @@ class QAPIDomain(Domain): "mod": QAPIXRefRole(), "cmd": QAPIXRefRole(), "enum": QAPIXRefRole(), + "alt": QAPIXRefRole(), # reference any data type (excludes modules, commands, events) "type": QAPIXRefRole(), "obj": QAPIXRefRole(), # reference *any* type of QAPI object. From patchwork Fri Dec 13 01:12:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906254 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 10881E7717F for ; Fri, 13 Dec 2024 01:15:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGV-0006dN-BX; Thu, 12 Dec 2024 20:14:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGL-0006KT-FY for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:39 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGJ-0000gD-BN for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052474; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RjR6Dh3llFPbmI/ayJ4ez1ETl3X50WyFlceVILBfRUE=; b=EXNfiBGnfVaHwLuhUunSYTD7tY/OiBFKmVwyLmlYILX7mKp1isR6Omlg/lHmsd5BXw77DN wrMDnEB1MZ60nkMKnmMCthyVorj8YIwnjDivZ7kqgJwIKbPGL5OT1jsqSl2UAQI49BmILZ 6opQT3rm6LLNPTN6AFqzqKfs4whXDKU= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-562-Z2fGFwFDNaqE99usK9--Zg-1; Thu, 12 Dec 2024 20:14:31 -0500 X-MC-Unique: Z2fGFwFDNaqE99usK9--Zg-1 X-Mimecast-MFC-AGG-ID: Z2fGFwFDNaqE99usK9--Zg Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9336B195608C; Fri, 13 Dec 2024 01:14:30 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3B4741956086; Fri, 13 Dec 2024 01:14:28 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 20/35] docs/qapi-domain: add qapi:event directive Date: Thu, 12 Dec 2024 20:12:49 -0500 Message-ID: <20241213011307.2942030-21-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Adds the .. qapi:event:: directive, object, and :qapi:event:`name` cross-referencing role. Adds the :memb type name: field list syntax for documenting event data members. As this syntax and phrasing will be shared with Structs and Unions as well, add the field list definition to a shared abstract class. As per usual, QAPI cross-referencing for types in the member field list will be added in a forthcoming commit. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index e0c31b2ee4d..e042421016f 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -321,6 +321,29 @@ class QAPIAlternate(QAPIObject): ) +class QAPIObjectWithMembers(QAPIObject): + """Base class for Events/Structs/Unions""" + + doc_field_types = QAPIObject.doc_field_types.copy() + doc_field_types.extend( + [ + # :member type name: descr + TypedField( + "member", + label=_("Members"), + names=("memb",), + can_collapse=False, + ), + ] + ) + + +class QAPIEvent(QAPIObjectWithMembers): + """Description of a QAPI Event.""" + + pass + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -481,6 +504,7 @@ class QAPIDomain(Domain): object_types: Dict[str, ObjType] = { "module": ObjType(_("module"), "mod", "obj"), "command": ObjType(_("command"), "cmd", "obj"), + "event": ObjType(_("event"), "event", "obj"), "enum": ObjType(_("enum"), "enum", "obj", "type"), "alternate": ObjType(_("alternate"), "alt", "obj", "type"), } @@ -490,6 +514,7 @@ class QAPIDomain(Domain): directives = { "module": QAPIModule, "command": QAPICommand, + "event": QAPIEvent, "enum": QAPIEnum, "alternate": QAPIAlternate, } @@ -500,6 +525,7 @@ class QAPIDomain(Domain): roles = { "mod": QAPIXRefRole(), "cmd": QAPIXRefRole(), + "event": QAPIXRefRole(), "enum": QAPIXRefRole(), "alt": QAPIXRefRole(), # reference any data type (excludes modules, commands, events) From patchwork Fri Dec 13 01:12:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906263 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AB8EFE7717F for ; Fri, 13 Dec 2024 01:17:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuI5-0002Lq-5c; Thu, 12 Dec 2024 20:16:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuHY-0001TF-TH for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:57 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuHS-0001BC-Jc for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052545; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rBgNkaG4dv2YJJtgU9QuV3617bD/FTejS/XKs7tm4ow=; b=iHw81wsGBfqxuWSWLfj7yiWXzJJoAqMw58lG0y+Exf/7V+9WLazAXQOo+I7+50y+s7HgDj UX95wpZ3s3Od/h+RgoUrsDVHNmcnF2qUaqADEMukPVXV1nyRPx5Xq91tpsQpTAEXDUT60r ciMrL/BLUGXoq1gkU89/1K1knReYIKU= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-124-EI1vaC3QNq-Cus2o4mtwTw-1; Thu, 12 Dec 2024 20:14:35 -0500 X-MC-Unique: EI1vaC3QNq-Cus2o4mtwTw-1 X-Mimecast-MFC-AGG-ID: EI1vaC3QNq-Cus2o4mtwTw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8FA4B195609F; Fri, 13 Dec 2024 01:14:34 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0310F1956086; Fri, 13 Dec 2024 01:14:30 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 21/35] docs/qapi-domain: add qapi:struct directive Date: Thu, 12 Dec 2024 20:12:50 -0500 Message-ID: <20241213011307.2942030-22-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Adds the .. qapi:struct:: directive, object, and :qapi:struct:`name` cross-referencing role. As per usual, QAPI cross-referencing for types in the member field list will be added in a forthcoming commit. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index e042421016f..d94d84bc186 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -344,6 +344,12 @@ class QAPIEvent(QAPIObjectWithMembers): pass +class QAPIStruct(QAPIObjectWithMembers): + """Description of a QAPI Struct.""" + + pass + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -506,6 +512,7 @@ class QAPIDomain(Domain): "command": ObjType(_("command"), "cmd", "obj"), "event": ObjType(_("event"), "event", "obj"), "enum": ObjType(_("enum"), "enum", "obj", "type"), + "struct": ObjType(_("struct"), "struct", "obj", "type"), "alternate": ObjType(_("alternate"), "alt", "obj", "type"), } @@ -516,6 +523,7 @@ class QAPIDomain(Domain): "command": QAPICommand, "event": QAPIEvent, "enum": QAPIEnum, + "struct": QAPIStruct, "alternate": QAPIAlternate, } @@ -527,6 +535,7 @@ class QAPIDomain(Domain): "cmd": QAPIXRefRole(), "event": QAPIXRefRole(), "enum": QAPIXRefRole(), + "struct": QAPIXRefRole(), "alt": QAPIXRefRole(), # reference any data type (excludes modules, commands, events) "type": QAPIXRefRole(), From patchwork Fri Dec 13 01:12:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906270 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DE411E77182 for ; Fri, 13 Dec 2024 01:18:30 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGX-0006oJ-MM; Thu, 12 Dec 2024 20:14:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGT-0006Su-DR for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:45 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGQ-0000gs-D3 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052481; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MIVqyDilLcqQD1IKvAN5ynNRWxlNH72emaCqA8E27/k=; b=RTY2j3zekcL4ggtyMNknU9/MgloZQgWbT5sc8iPdFHrmjzOKyzBCm4E3NuP50usflydV3z xE2Z5pLjTL1sgH1+nx8QrNpYmKqvQo12jPOXu4TL8MoH4+d2CzQ/H+h07HhknXtl/5bvdA bOJFEUdIx4gth41+DF+sejcVYLM+9sU= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-441-ntPU_juhP9S7gdi5YfozUA-1; Thu, 12 Dec 2024 20:14:39 -0500 X-MC-Unique: ntPU_juhP9S7gdi5YfozUA-1 X-Mimecast-MFC-AGG-ID: ntPU_juhP9S7gdi5YfozUA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8D2FA195609E; Fri, 13 Dec 2024 01:14:38 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2CCC11956086; Fri, 13 Dec 2024 01:14:34 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 22/35] docs/qapi-domain: add qapi:union and qapi:branch directives Date: Thu, 12 Dec 2024 20:12:51 -0500 Message-ID: <20241213011307.2942030-23-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Adds the .. qapi:union:: directive, object, and :qapi:union:`name` cross-referencing role. In order to support discriminated branches of unions, a new qapi:branch directive is created whose only purpose is to create a dynamically named field list section based on the name of the branch key and value. Because the label for these branch sections is dynamically generated, this patch allows the use of either :memb: or :arg: in branches; they are simply aliases and do not do anything different. (This is to allow the directive to be used for either Commands or Unions as needed; i.e. for commands whose argument type is a discriminated union.) For example: .. qapi:union:: foo-union :memb foo-enum key: Discriminator field :memb foo-type fieldname: Some base type field that is always present .. qapi:branch:: key value1 :memb type name: lorem ipsum ... .. qapi:branch:: key value2 :memb type2 name2: dolor sit amet ... In order to support this syntax, the root QAPIObject class needs to perform some post-processing on field lists to merge adjecent field lists. because each branch directive will return a separate field list, and we want to combine them into one unified list for proper rendering. NOTE: Technically, the branch directive will allow you to put arbitrary ReST besides field lists inside of it, but it almost certainly won't do anything you'd consider useful. I don't recommend it, but programmatically forbidding it is expensive. Recommendation: "Don't!" ... and now ... RFC: The branches abuse the field list system to create new categories of field list entries that are dynamically generated. At the moment, I do not have code to apply appropriate formatting to these headings, but would like to apply ``literal`` syntax at a minimum to the enum values. The other idea I have is to create a "blank" members value that doesn't add a "title" (field label) on the left column and instead adds a horizontal info bar into the arguments list in the right, but the problem with this approach is that I won't be able to get rid of the "* ..." list bullet syntax, so it may look odd. Otherwise, a benefit to this syntax is that it would allow us to write a longer explanation, e.g. "When ``{key}`` is ``{value}``". It's possible I could split the argument list into several nested lists, but I haven't experimented in that direction yet - it's also likely that Sphinx will want to append a ":" even to blank section titles, so this may prove tricky to do within the constraints of Sphinx's existing Field list system. (I believe the HTML formatter is responsible for appending the colons.) I'm open to suggestions, but wrestling with Sphinx, html and css is time consuming (for me, at least), so ultimately, I'm afraid I must say: ***PATCHES WELCOME***. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 105 ++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index d94d84bc186..6120515bdc8 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -34,7 +34,12 @@ from sphinx.locale import _, __ from sphinx.roles import XRefRole from sphinx.util import logging -from sphinx.util.docfields import Field, GroupedField, TypedField +from sphinx.util.docfields import ( + DocFieldTransformer, + Field, + GroupedField, + TypedField, +) from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_id, make_refnode @@ -49,6 +54,8 @@ logger = logging.getLogger(__name__) +quack = cast # O:-) + class ObjectEntry(NamedTuple): docname: str @@ -229,6 +236,35 @@ def add_target_and_index( ("single", indextext, node_id, "", None) ) + def _merge_adjoining_field_lists( + self, contentnode: addnodes.desc_content + ) -> None: + # Take any adjacent field lists and glue them together into + # one list for further processing by Sphinx. This is done so + # that field lists declared in nested directives can be + # flattened into non-nested field lists. + # + # This only impacts field lists at the root level of the Object + # Description. + + first_list = None + delete_queue: List[nodes.field_list] = [] + for child in contentnode: + if isinstance(child, nodes.field_list): + if not first_list: + first_list = child + else: + first_list += child.children + delete_queue.append(child) + else: + first_list = None + + for child in delete_queue: + contentnode.remove(child) + + def transform_content(self, contentnode: addnodes.desc_content) -> None: + self._merge_adjoining_field_lists(contentnode) + def _toc_entry_name(self, sig_node: desc_signature) -> str: # This controls the name in the TOC and on the sidebar. @@ -350,6 +386,12 @@ class QAPIStruct(QAPIObjectWithMembers): pass +class QAPIUnion(QAPIObjectWithMembers): + """Description of a QAPI Union.""" + + pass + + class QAPIModule(SphinxDirective): """ Directive to mark description of a new module. @@ -440,6 +482,61 @@ def run(self) -> List[Node]: return ret +class Branch(SphinxDirective): + """ + Nested directive which only serves to introduce temporary + metadata but return its parsed content nodes unaltered otherwise. + + Technically, you can put whatever you want in here, but doing so may + prevent proper merging of adjacent field lists. + """ + + doc_field_types: List[Field] = [] + has_content = True + required_arguments = 2 + optional_arguments = 0 + domain = "qapi" + + def get_field_type_map(self) -> Dict[str, Tuple[Field, bool]]: + ret = {} + for field in self.doc_field_types: + for name in field.names: + ret[name] = (field, False) + + if field.is_typed: + typed_field = cast(TypedField, field) + for name in typed_field.typenames: + ret[name] = (field, True) + return ret + + def run(self) -> list[Node]: + discrim = self.arguments[0].strip() + value = self.arguments[1].strip() + + # The label name is dynamically generated per-instance instead + # of per-class to incorporate the branch conditions as a label + # name. + self.doc_field_types = [ + # :arg type name: descr + # :memb type name: descr + TypedField( + "branch-arg-or-memb", + label=f"[{discrim} = {value}]", + # In a branch, we don't actually use the name of the + # field name to generate the label; so allow either-or. + names=("arg", "memb"), + ), + ] + + content_node: addnodes.desc_content = addnodes.desc_content() + nested_parse(self, content_node) + # DocFieldTransformer usually expects ObjectDescription, but... quack! + transformer = DocFieldTransformer(quack(ObjectDescription, self)) + transformer.transform_all(content_node) + + return content_node.children + + class QAPIIndex(Index): """ Index subclass to provide the QAPI definition index. @@ -514,6 +611,7 @@ class QAPIDomain(Domain): "enum": ObjType(_("enum"), "enum", "obj", "type"), "struct": ObjType(_("struct"), "struct", "obj", "type"), "alternate": ObjType(_("alternate"), "alt", "obj", "type"), + "union": ObjType(_("union"), "union", "obj", "type"), } # Each of these provides a rST directive, @@ -525,6 +623,10 @@ class QAPIDomain(Domain): "enum": QAPIEnum, "struct": QAPIStruct, "alternate": QAPIAlternate, + "union": QAPIUnion, + # This is not an object in its own right; + # It's a directive for documenting branch members of Union types. + "branch": Branch, } # These are all cross-reference roles; e.g. @@ -537,6 +639,7 @@ class QAPIDomain(Domain): "enum": QAPIXRefRole(), "struct": QAPIXRefRole(), "alt": QAPIXRefRole(), + "union": QAPIXRefRole(), # reference any data type (excludes modules, commands, events) "type": QAPIXRefRole(), "obj": QAPIXRefRole(), # reference *any* type of QAPI object. From patchwork Fri Dec 13 01:12:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906251 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 20BB3E77180 for ; Fri, 13 Dec 2024 01:15:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGa-000702-UF; Thu, 12 Dec 2024 20:14:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGY-0006rY-1e for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:50 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGW-0000hM-1E for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052487; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3tf5xaSO0EkHds5mMKncBH7RfG7ylI74BQWD6+y1RW8=; b=aels56WYJFC1fW5FNA1aNEEGX9AVPkAULbr28rDAj65xa4Dzk7XCJBbNFpy86dH3+OVA/u sa3LhUKUF5xZ6H93AdYzJ+xrsuvD8CVahXSI+OGvUjBxk1TvYiTEHqMwVI5L+Sz6wcEOax xHCGwsNt6siEiYwFptcKWlErKe76dfs= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-311-xaMJMyntOI67NvZQovKM_g-1; Thu, 12 Dec 2024 20:14:44 -0500 X-MC-Unique: xaMJMyntOI67NvZQovKM_g-1 X-Mimecast-MFC-AGG-ID: xaMJMyntOI67NvZQovKM_g Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2E8B319560B3; Fri, 13 Dec 2024 01:14:43 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 60C851956086; Fri, 13 Dec 2024 01:14:39 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow , Harmonie Snow Subject: [RFC PATCH v2 23/35] docs/qapi-domain: add :deprecated: directive option Date: Thu, 12 Dec 2024 20:12:52 -0500 Message-ID: <20241213011307.2942030-24-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Although "deprecated" is a feature (and *will* appear in the features list), add a special :deprecated: option to generate an eye-catch that makes this information very hard to miss. (The intent is to modify qapidoc.py to add this option whenever it detects that the features list attached to a definition contains the "deprecated" entry.) - RFC: Technically, this object-level option is un-needed and could be replaced with a standard content-level directive that e.g. qapidoc.py could insert at the beginning of the content block. I've done it here as an option to demonstrate how it would be possible to do. It's a matter of taste for "where" we feel like implementing it. One benefit of doing it this way is that we can create a single containing box to set CSS style options controlling the flow of multiple infoboxes. The other way to achieve that would be to create a directive that allows us to set multiple options instead, e.g.: .. qapi:infoboxes:: deprecated unstable or possibly: .. qapi:infoboxes:: :deprecated: :unstable: For now, I've left these as top-level QAPI object options. "Hey, it works." P.S., I outsourced the CSS ;) Signed-off-by: Harmonie Snow Signed-off-by: John Snow --- docs/sphinx-static/theme_overrides.css | 25 +++++++++++++++++++++++++ docs/sphinx/qapi-domain.py | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index 965ecac54fd..3765cab1b20 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -208,3 +208,28 @@ div[class^="highlight"] pre { color: inherit; } } + +/* QAPI domain theming */ + +.qapi-infopips { + margin-bottom: 1em; +} + +.qapi-infopip { + display: inline-block; + padding: 0em 0.5em 0em 0.5em; + margin: 0.25em; +} + +.qapi-deprecated { + background-color: #fffef5; + border: solid #fff176 6px; + font-weight: bold; + padding: 8px; + border-radius: 15px; + margin: 5px; +} + +.qapi-deprecated::before { + content: '⚠️ '; +} diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 6120515bdc8..b33d9927f4d 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -126,6 +126,7 @@ class QAPIObject(ObjectDescription[Signature]): "module": directives.unchanged, # Override contextual module name # These are QAPI originals: "since": since_validator, + "deprecated": directives.flag, } ) @@ -236,6 +237,28 @@ def add_target_and_index( ("single", indextext, node_id, "", None) ) + def _add_infopips(self, contentnode: addnodes.desc_content) -> None: + # Add various eye-catches and things that go below the signature + # bar, but precede the user-defined content. + infopips = nodes.container() + infopips.attributes["classes"].append("qapi-infopips") + + def _add_pip(source: str, content: str, classname: str) -> None: + node = nodes.container(source) + node.append(nodes.Text(content)) + node.attributes["classes"].extend(["qapi-infopip", classname]) + infopips.append(node) + + if "deprecated" in self.options: + _add_pip( + ":deprecated:", + f"This {self.objtype} is deprecated.", + "qapi-deprecated", + ) + + if infopips.children: + contentnode.insert(0, infopips) + def _merge_adjoining_field_lists( self, contentnode: addnodes.desc_content ) -> None: @@ -263,6 +286,7 @@ def _merge_adjoining_field_lists( contentnode.remove(child) def transform_content(self, contentnode: addnodes.desc_content) -> None: + self._add_infopips(contentnode) self._merge_adjoining_field_lists(contentnode) def _toc_entry_name(self, sig_node: desc_signature) -> str: From patchwork Fri Dec 13 01:12:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906252 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 192EFE7717F for ; Fri, 13 Dec 2024 01:15:16 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGj-0007fp-Po; Thu, 12 Dec 2024 20:15:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGg-0007SI-RJ for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:59 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGa-0000ho-UH for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:14:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052492; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k7AOJLSgaxPGr334OEFUTdnH0SfzGN2bBVrUU6r0Wqs=; b=Gm1sYUxZAdvZT7Qqw+sT3zkqWvlasd6cVAiOMNjLEjdELJ7uI1cK3h4qA17TPsKlmd9wyA bMu3OZMkpRC43a62ahrCWH+6Pt/uQ0L+wogtikJCMmsN5DNgkak7pYltUNHh6a/5QZIEjd e7Cu5s2SFIDS8pXvN7Qz9IQoWOJQ3OU= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-164-E4vyYFvxN-i10cUNUp3n8w-1; Thu, 12 Dec 2024 20:14:47 -0500 X-MC-Unique: E4vyYFvxN-i10cUNUp3n8w-1 X-Mimecast-MFC-AGG-ID: E4vyYFvxN-i10cUNUp3n8w Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D5454195608A; Fri, 13 Dec 2024 01:14:46 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 228C01956086; Fri, 13 Dec 2024 01:14:43 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow , Harmonie Snow Subject: [RFC PATCH v2 24/35] docs/qapi-domain: add :unstable: directive option Date: Thu, 12 Dec 2024 20:12:53 -0500 Message-ID: <20241213011307.2942030-25-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Although "unstable" is a feature (and *will* appear in the features list), add a special :unstable: option to generate an eye-catch that makes this information very hard to miss. (The intent is to modify qapidoc.py to add this option whenever it detects that the features list attached to a definition contains the "unstable" entry.) RFC: Same comments as last patch. Signed-off-by: Harmonie Snow Signed-off-by: John Snow --- docs/sphinx-static/theme_overrides.css | 6 +++++- docs/sphinx/qapi-domain.py | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index 3765cab1b20..5f58f1d5246 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -221,7 +221,7 @@ div[class^="highlight"] pre { margin: 0.25em; } -.qapi-deprecated { +.qapi-deprecated,.qapi-unstable { background-color: #fffef5; border: solid #fff176 6px; font-weight: bold; @@ -230,6 +230,10 @@ div[class^="highlight"] pre { margin: 5px; } +.qapi-unstable::before { + content: ' From patchwork Fri Dec 13 01:12:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906272 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 85807E7717F for ; Fri, 13 Dec 2024 01:18:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGu-0008JL-7P; Thu, 12 Dec 2024 20:15:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGo-0007yh-KJ for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:08 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGf-0000hy-M3 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BsM1OIJt181TdMGUiq9c24NHPTZFUCynBtcB5irAS+k=; b=hhg0TKnyeq3qL16Jyw0Bx3ULribhLKOnR3fPyy140jAFGR5caAGSCd/BeKGjvzYNJAJew4 qEIzW6famgTThmpFnV/nCMmINGfxnyKvkLJKY2hjzD28t+hShL3lsor/LF/EQ7vFy/KJjH 0wG8teZbh+MVukAlDU08WyQOD98UBLU= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-126-Eu7c0v-JNieCNvZcJNfpfA-1; Thu, 12 Dec 2024 20:14:51 -0500 X-MC-Unique: Eu7c0v-JNieCNvZcJNfpfA-1 X-Mimecast-MFC-AGG-ID: Eu7c0v-JNieCNvZcJNfpfA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1375619560B7; Fri, 13 Dec 2024 01:14:50 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 25CFE1956086; Fri, 13 Dec 2024 01:14:46 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow , Harmonie Snow Subject: [RFC PATCH v2 25/35] docs/qapi-domain: add :ifcond: directive option Date: Thu, 12 Dec 2024 20:12:54 -0500 Message-ID: <20241213011307.2942030-26-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a special :ifcond: option that allows us to annotate the definition-level conditionals. RFC: This patch renders IFCOND information in two places, because I'm undecided about how to style this information. One option is in the signature bar, and another option is in an eye-catch, like :deprecated: or :unstable:. A benefit to having this be a directive option is that we can put it in the signature bar, the QAPI index, etc. However, if we merely want it in the content section, a directive would work just as well, e.g. ".. qapi:ifcond:: CONFIG_LINUX". (Though, having it be in the same containing box as the unstable/ifcond boxes might require some extra fiddling/post-processing to achieve. Generally, the less docutils tree muddling I have to do, the happier I am.) The syntax of the argument is currently undefined, but it is possible to parse it back down into constituent parts to avoid applying literal formatting to "AND" or "&&" or whichever syntax we formalize. (Or, in the future, applying cross-reference links to the config values for additional reading on some of those build options. Not for this series.) "Vote now on your phones!" Signed-off-by: Harmonie Snow Signed-off-by: John Snow --- docs/sphinx-static/theme_overrides.css | 13 +++++++++ docs/sphinx/qapi-domain.py | 39 ++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index 5f58f1d5246..3fd326613d9 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -237,3 +237,16 @@ div[class^="highlight"] pre { .qapi-deprecated::before { content: '⚠️ '; } + +.qapi-ifcond::before { + /* gaze ye into the crystal ball to determine feature availability */ + content: ' From patchwork Fri Dec 13 01:12:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906262 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E74D7E77180 for ; Fri, 13 Dec 2024 01:16:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGm-0007jk-6S; Thu, 12 Dec 2024 20:15:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGi-0007XJ-FA for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:00 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGg-0000i0-5j for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fcuiOMT3uLSddjTINzRUt/NUAzts5LxaEcR7TXL6FJQ=; b=O/Z7RYaQZStZKYHhlYDzBWqw12VLnfHxy/Fqx1oyV9oo5QXzDkoTsFdrzHSd1dkEaNgmuv 6LTNN6+Mb6Km5Avac5Ua/cXLh/gyvoUXTaTw7KmmxHZ6x721m/qwa6kPl5Z0/mHujzPGFH cpvK1itxPPhxeGFPh5ilRM12N8f/nK0= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-180-4yWFKl7IPkyGClQD2RuukQ-1; Thu, 12 Dec 2024 20:14:54 -0500 X-MC-Unique: 4yWFKl7IPkyGClQD2RuukQ-1 X-Mimecast-MFC-AGG-ID: 4yWFKl7IPkyGClQD2RuukQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3ADB819560A3; Fri, 13 Dec 2024 01:14:53 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 82A2B1956086; Fri, 13 Dec 2024 01:14:50 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 26/35] docs/qapi-domain: add warnings for malformed field lists Date: Thu, 12 Dec 2024 20:12:55 -0500 Message-ID: <20241213011307.2942030-27-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Normally, Sphinx will silently fall back to its standard field list processing if it doesn't match one of your defined fields. A lot of the time, that's not what we want - we want to be warned if we goof something up. For instance, the canonical argument field list form is: :arg type name: descr This form is captured by Sphinx and transformed so that the field label will become "Arguments:". It's possible to omit the type name and descr and still have it be processed correctly. However, if you omit the type name, Sphinx no longer recognizes it: :arg: this is not recognized. This will turn into an arbitrary field list entry whose label is "Arg:", and it otherwise silently fails. You may also see failures for doing things like using :values: instead of :value:, or :errors: instead of :error:, and so on. It's also case sensitive, and easy to trip up. Add a validator that guarantees all field list entries that are the direct child of an ObjectDescription use only recognized forms of field lists, and emit a warning (treated as error by default in most build configurations) whenever we detect one that is goofed up. However, there's still benefit to allowing arbitrary fields -- they are after all not a Sphinx invention, but perfectly normal docutils syntax. Create an allow list for known spellings we don't mind letting through, but warn against anything else. Signed-off-by: John Snow --- docs/conf.py | 9 +++++ docs/sphinx/qapi-domain.py | 80 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index f2986ef7d74..bad35114351 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -153,6 +153,15 @@ with open(os.path.join(qemu_docdir, 'defs.rst.inc')) as f: rst_epilog += f.read() + +# Normally, the QAPI domain is picky about what field lists you use to +# describe a QAPI entity. If you'd like to use arbitrary additional +# fields in source documentation, add them here. +qapi_allowed_fields = { + "see also", +} + + # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index f7c7aaa507f..ba1e52a1f77 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -58,6 +58,19 @@ quack = cast # O:-) +def _unpack_field( + field: nodes.Node, +) -> Tuple[nodes.field_name, nodes.field_body]: + """ + docutils helper: unpack a field node in a type-safe manner. + """ + assert isinstance(field, nodes.field) + assert len(field.children) == 2 + assert isinstance(field.children[0], nodes.field_name) + assert isinstance(field.children[1], nodes.field_body) + return (field.children[0], field.children[1]) + + class ObjectEntry(NamedTuple): docname: str node_id: str @@ -328,10 +341,71 @@ def _merge_adjoining_field_lists( for child in delete_queue: contentnode.remove(child) + def _validate_field(self, field: nodes.field) -> None: + """Validate field lists in this QAPI Object Description.""" + name, _ = _unpack_field(field) + allowed_fields = set(self.env.app.config.qapi_allowed_fields) + + field_label = name.astext() + if ( + re.match(r"\[\S+ = \S+\]", field_label) + or field_label in allowed_fields + ): + # okie-dokey. branch entry or known good allowed name. + return + + try: + # split into field type and argument (if provided) + # e.g. `:arg type name: descr` is + # field_type = "arg", field_arg = "type name". + field_type, field_arg = field_label.split(None, 1) + except ValueError: + # No arguments provided + field_type = field_label + field_arg = "" + + typemap = self.get_field_type_map() + if field_type in typemap: + # This is a special docfield, yet-to-be-processed. Catch + # correct names, but incorrect arguments. This mismatch WILL + # cause Sphinx to render this field incorrectly (without a + # warning), which is never what we want. + typedesc = typemap[field_type][0] + if typedesc.has_arg != bool(field_arg): + msg = f"docfield field list type {field_type!r} " + if typedesc.has_arg: + msg += "requires an argument." + else: + msg += "takes no arguments." + logger.warning(msg, location=field) + else: + # This is unrecognized entirely. It's valid rST to use + # arbitrary fields, but let's ensure the documentation + # writer has done this intentionally. + valid = ", ".join(sorted(set(typemap) | allowed_fields)) + msg = ( + f"Unrecognized field list name {field_label!r}.\n" + f"Valid fields for qapi:{self.objtype} are: {valid}\n" + "\n" + "If this usage is intentional, please add it to " + "'qapi_allowed_fields' in docs/conf.py." + ) + logger.warning(msg, location=field) + def transform_content(self, contentnode: addnodes.desc_content) -> None: self._add_infopips(contentnode) self._merge_adjoining_field_lists(contentnode) + # Validate field lists. Note that this hook runs after any + # branch directives have processed and transformed their field + # lists, but before the main object directive has had a chance + # to do so. + for child in contentnode: + if isinstance(child, nodes.field_list): + for field in child.children: + assert isinstance(field, nodes.field) + self._validate_field(field) + def _toc_entry_name(self, sig_node: desc_signature) -> str: # This controls the name in the TOC and on the sidebar. @@ -901,6 +975,12 @@ def resolve_any_xref( def setup(app: Sphinx) -> Dict[str, Any]: app.setup_extension("sphinx.directives") + app.add_config_value( + "qapi_allowed_fields", + set(), + "env", # Setting impacts parsing phase + types=set, + ) app.add_domain(QAPIDomain) return { From patchwork Fri Dec 13 01:12:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906297 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5FBE9E7717F for ; Fri, 13 Dec 2024 01:19:36 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGr-0008FA-WB; Thu, 12 Dec 2024 20:15:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGp-00084G-Oe for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:07 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGn-0000tm-Lc for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:07 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052504; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Fy89eOED+38llVWEs5a83zYeHZIY4d1VHdhXz1LxBdg=; b=f8wp/2cleRYHDEyXcrtqzOEWRj6kKy7fVwgb/ESe4C1Cv7gOynlRLqgVAAzgoqaUg0QHRo lAPLpFWO9qv6rT780nWeBMP05AyF63v/yeM6znHCqPiza154qahPqhinv7ihswyMrMKRcw 7vrB4H8IJGlA8dALZQwV2FAWyf4WqlI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-416-t2WJGzZiN7KetpN03f2UgQ-1; Thu, 12 Dec 2024 20:14:58 -0500 X-MC-Unique: t2WJGzZiN7KetpN03f2UgQ-1 X-Mimecast-MFC-AGG-ID: t2WJGzZiN7KetpN03f2UgQ Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ADA2B19560B8; Fri, 13 Dec 2024 01:14:56 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6F58F1956089; Fri, 13 Dec 2024 01:14:53 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 27/35] docs/qapi-domain: add type cross-refs to field lists Date: Thu, 12 Dec 2024 20:12:56 -0500 Message-ID: <20241213011307.2942030-28-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit, finally, adds cross-referencing support to various field lists; modeled tightly after Sphinx's own Python domain code. Cross-referencing support is added to type names provided to :arg:, :memb:, :returns: and :choice:. :feat:, :error: and :value:, which do not take type names, do not support this syntax. The general syntax is simple: :arg TypeName ArgName: Lorem Ipsum ... The domain will transform TypeName into :qapi:type:`TypeName` in this basic case, and also apply the ``literal`` decoration to indicate that this is a type cross-reference. For optional arguments, the special "?" suffix is used. Because "*" has special meaning in ReST that would cause parsing errors, we elect to use "?" instead. The special syntax processing in QAPIXrefMixin strips this character from the end of any type name argument and will append ", optional" to the rendered output, applying the cross-reference only to the actual type name. The intent here is that the actual syntax in doc-blocks need not change; but e.g. qapidoc.py will need to process and transform "@arg foo lorem ipsum" into ":arg type? foo: lorem ipsum" based on the schema information. Therefore, nobody should ever actually witness this intermediate syntax unless they are writing manual documentation or the doc transmogrifier breaks. For array arguments, type names can similarly be surrounded by "[]", which are stripped off and then re-appended outside of the cross-reference. Note: The mixin pattern here (borrowed from Sphinx) confuses mypy because it cannot tell that it will be mixed into a descendent of Field. Doing that instead causes more errors, because many versions of Sphinx erroneously did not mark various arguments as Optional, so we're a bit hosed either way. Do the simpler thing. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 136 +++++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 7 deletions(-) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index ba1e52a1f77..907ba6d27d3 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -47,11 +47,12 @@ if TYPE_CHECKING: from docutils.nodes import Element, Node + from docutils.parsers.rst.states import Inliner from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import OptionSpec, TextlikeNode logger = logging.getLogger(__name__) @@ -78,6 +79,110 @@ class ObjectEntry(NamedTuple): aliased: bool +class QAPIXrefMixin: + def make_xref( + self, + rolename: str, + domain: str, + target: str, + innernode: type[TextlikeNode] = nodes.literal, + contnode: Optional[Node] = None, + env: Optional[BuildEnvironment] = None, + inliner: Optional[Inliner] = None, + location: Optional[Node] = None, + ) -> Node: + # make_xref apparently has a mode of operation where the inliner + # class argument is passed to the role object + # (e.g. QAPIXRefRole) to construct the final result; passing + # inliner = location = None forces it into its legacy mode where + # it returns a pending_xref node instead. + # (This is how the built-in Python domain behaves.) + result = super().make_xref( # type: ignore[misc] + rolename, + domain, + target, + innernode=innernode, + contnode=contnode, + env=env, + inliner=None, + location=None, + ) + if isinstance(result, pending_xref): + assert env is not None + # Add domain-specific context information to the pending reference. + result["refspecific"] = True + result["qapi:module"] = env.ref_context.get("qapi:module") + + assert isinstance(result, nodes.Node) + return result + + def make_xrefs( + self, + rolename: str, + domain: str, + target: str, + innernode: type[TextlikeNode] = nodes.literal, + contnode: Optional[Node] = None, + env: Optional[BuildEnvironment] = None, + inliner: Optional[Inliner] = None, + location: Optional[Node] = None, + ) -> list[Node]: + # Note: this function is called on up to three fields of text: + # (1) The field name argument (e.g. member/arg name) + # (2) The field name type (e.g. member/arg type) + # (3) The field *body* text, for Fields that do not take arguments. + + list_type = False + optional = False + + # If the rolename is qapi:type, we know we are processing a type + # and not an arg/memb name or field body text. + if rolename == "type": + # force the innernode class to be a literal. + innernode = nodes.literal + + # Type names that end with "?" are considered Optional + # arguments and should be documented as such, but it's not + # part of the xref itself. + if target.endswith("?"): + optional = True + target = target[:-1] + + # Type names wrapped in brackets denote lists. strip the + # brackets and remember to add them back later. + if target.startswith("[") and target.endswith("]"): + list_type = True + target = target[1:-1] + + # When processing Fields with bodyrolename="type", contnode + # will be present, which indicates that the body has already + # been parsed into nodes. We don't want that, actually: + # we'll re-create our own nodes for it. + contnode = None + + results = [] + result = self.make_xref( + rolename, + domain, + target, + innernode, + contnode, + env, + inliner, + location, + ) + results.append(result) + + if list_type: + results.insert(0, nodes.literal("[", "[")) + results.append(nodes.literal("]", "]")) + if optional: + results.append(nodes.Text(", ")) + results.append(nodes.emphasis("?", "optional")) + + return results + + class QAPIXRefRole(XRefRole): def process_link( self, @@ -106,6 +211,18 @@ def process_link( return title, target +class QAPIGroupedField(QAPIXrefMixin, GroupedField): + pass + + +class QAPITypedField(QAPIXrefMixin, TypedField): + pass + + +class QAPIField(QAPIXrefMixin, Field): + pass + + def since_validator(param: str) -> str: """ Validate the `:since: X.Y` option field. @@ -432,10 +549,11 @@ class QAPICommand(QAPIObject): doc_field_types.extend( [ # :arg TypeName ArgName: descr - TypedField( + QAPITypedField( "argument", label=_("Arguments"), names=("arg",), + typerolename="type", can_collapse=False, ), # :error: descr @@ -446,14 +564,15 @@ class QAPICommand(QAPIObject): has_arg=False, ), # :returns TypeName: descr - GroupedField( + QAPIGroupedField( "returnvalue", label=_("Returns"), + rolename="type", names=("return", "returns"), can_collapse=True, ), # :returns-nodesc: TypeName - Field( + QAPIField( "returnvalue", label=_("Returns"), names=("returns-nodesc",), @@ -488,10 +607,11 @@ class QAPIAlternate(QAPIObject): doc_field_types.extend( [ # :choice type name: descr - TypedField( + QAPITypedField( "choice", label=_("Choices"), names=("choice",), + typerolename="type", can_collapse=False, ), ] @@ -505,10 +625,11 @@ class QAPIObjectWithMembers(QAPIObject): doc_field_types.extend( [ # :member type name: descr - TypedField( + QAPITypedField( "member", label=_("Members"), names=("memb",), + typerolename="type", can_collapse=False, ), ] @@ -660,12 +781,13 @@ def run(self) -> list[Node]: self.doc_field_types = [ # :arg type name: descr # :memb type name: descr - TypedField( + QAPITypedField( "branch-arg-or-memb", label=f"[{discrim} = {value}]", # In a branch, we don't actually use the name of the # field name to generate the label; so allow either-or. names=("arg", "memb"), + typerolename="type", ), ] From patchwork Fri Dec 13 01:12:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906268 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 50D35E77182 for ; Fri, 13 Dec 2024 01:18:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuH0-0000TE-P4; Thu, 12 Dec 2024 20:15:18 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGy-0000FI-Iv for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:16 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGo-0000to-Di for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052504; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=w11qbz5LS8mfp4Zf8SPjOFvm9fv3TsBf+zaZUYZeWXc=; b=EyNvPpxWDWkI6nxczKj9vcJQM2BiJe20jfaXUtDHGjJRsznMTk6aOXnNIW2kPwI1aWvsMX HsuIp3V8ukfxQ+MkUTnrjKfoKe68qCALR22jPHPbFk6/tIRa70dqYX11L3vqtKLATKCzrY Eu290Yk53Ht+WgHcoor+mMu4NxDge2Y= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-659-War67uLBP1GD292nBirB1Q-1; Thu, 12 Dec 2024 20:15:00 -0500 X-MC-Unique: War67uLBP1GD292nBirB1Q-1 X-Mimecast-MFC-AGG-ID: War67uLBP1GD292nBirB1Q Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 91B9E1956095; Fri, 13 Dec 2024 01:14:59 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0B9841956086; Fri, 13 Dec 2024 01:14:56 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , Harmonie Snow , John Snow Subject: [RFC PATCH v2 28/35] docs/qapi-domain: add CSS styling Date: Thu, 12 Dec 2024 20:12:57 -0500 Message-ID: <20241213011307.2942030-29-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Harmonie Snow Improve the general look and feel of generated QAPI docs. Attempt to limit line lengths to offer a more comfortable measure on maximized windows, and improve some margin and spacing for field lists. Signed-off-by: Harmonie Snow Signed-off-by: John Snow --- docs/sphinx-static/theme_overrides.css | 50 ++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index 3fd326613d9..5ceb89eb9a8 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -18,8 +18,8 @@ h1, h2, .rst-content .toctree-wrapper p.caption, h3, h4, h5, h6, legend { .rst-content dl:not(.docutils) dt { border-top: none; - border-left: solid 3px #ccc; - background-color: #f0f0f0; + border-left: solid 5px #bcc6d2; + background-color: #eaedf1; color: black; } @@ -211,6 +211,18 @@ div[class^="highlight"] pre { /* QAPI domain theming */ +/* most content in a qapi object definition should not eclipse about + 80ch, but nested field lists are explicitly exempt due to their + two-column nature */ +.qapi dd *:not(dl) { + max-width: 80ch; +} + +/* but the content column itself should still be less than ~80ch. */ +.qapi .field-list dd { + max-width: 80ch; +} + .qapi-infopips { margin-bottom: 1em; } @@ -250,3 +262,37 @@ div[class^="highlight"] pre { border-radius: 15px; margin: 5px; } + +/* code blocks */ +.qapi div[class^="highlight"] { + width: fit-content; + background-color: #fffafd; + border: 2px solid #ffe1f3; +} + +/* note, warning, etc. */ +.qapi .admonition { + width: fit-content; +} + +/* pad the top of the field-list so the text doesn't start directly at + the top border; primarily for the field list labels, but adjust the + field bodies as well for parity. */ +dl.field-list > dt:first-of-type, dl.field-list > dd:first-of-type { + padding-top: 0.3em; +} + +dl.field-list > dt:last-of-type, dl.field-list > dd:last-of-type { + padding-bottom: 0.3em; +} + +/* pad the field list labels so they don't crash into the border */ +dl.field-list > dt { + padding-left: 0.5em; + padding-right: 0.5em; +} + +/* Add a little padding between field list sections */ +dl.field-list > dd:not(:last-child) { + padding-bottom: 1em; +} From patchwork Fri Dec 13 01:12:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906294 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 60922E7717F for ; Fri, 13 Dec 2024 01:19:03 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuH1-0000ZM-G3; Thu, 12 Dec 2024 20:15:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGz-0000Ly-L5 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:17 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGt-0000uk-H5 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052508; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oIVykYglNzfjCvyW2Izk/HQ4KymL73UyLf8Jai2qlWs=; b=W/R60TUaWtGDqZCSAQv6dAhNFwG7u3e5kL86snI77Q9+B6TxVcytvudkuPA386c8s/P2Hl xQmSibsMe/ClOC4s6OwTtgx1S7ubDpqPjYP+vDWDTMxAWT4dpTz1FhXuPe+t1HrtP1iz0L 2ZBXv08BjlPm+0oh0ncgJam/5U7VO4o= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-563-9HjEOfLnOqSLob7q2p_gfg-1; Thu, 12 Dec 2024 20:15:05 -0500 X-MC-Unique: 9HjEOfLnOqSLob7q2p_gfg-1 X-Mimecast-MFC-AGG-ID: 9HjEOfLnOqSLob7q2p_gfg Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5E28119560BD; Fri, 13 Dec 2024 01:15:04 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B6E851956086; Fri, 13 Dec 2024 01:14:59 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 29/35] docs/qapi-domain: warn when QAPI domain xrefs fail to resolve Date: Thu, 12 Dec 2024 20:12:58 -0500 Message-ID: <20241213011307.2942030-30-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Ignore the built-in JSON doc types, but warn about anything else. This is primarily here to assert that the cross-referencing system is complete and accurate, and that any cross-references the transmogrifier generates are correctly marked as visible and rendered/indexed by the qapi-domain. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 907ba6d27d3..8dbf0ee5e70 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -1060,6 +1060,16 @@ def resolve_xref( multiple_matches = len(matches) > 1 if not matches: + if target not in ( + "string", + "number", + "int", + "boolean", + "null", + "value", + "q_empty", + ): + print(f"!QXREF: {type=} {target=}") return None elif multiple_matches: logger.warning( From patchwork Fri Dec 13 01:12:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906260 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 69AE7E77180 for ; Fri, 13 Dec 2024 01:16:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuGz-0000JS-FU; Thu, 12 Dec 2024 20:15:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGy-0000Du-6E for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:16 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGs-0000uz-Lu for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052510; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MPtM0t9j3+VUBJU/haXesLXFHdebw1mTjI3ZE0OFdKY=; b=LAgH5ryN+nGPhFIWK3DQeJOygIPBOxcNE6gsMNj9M6M9tz8NsFCTU+i86WFyBb88EWrdf6 uYZDnBdM8IMmEN8nRgnuOf0JSfDB8qaUa2TjAXUhNiO90fQjzhKp8atQY+rtjL+u6uxlXH /A9gwgQSGKEjcwx4ZkzouMqonvAqGv8= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-15-GtaoVxW-OPqGPgA96HvLKw-1; Thu, 12 Dec 2024 20:15:08 -0500 X-MC-Unique: GtaoVxW-OPqGPgA96HvLKw-1 X-Mimecast-MFC-AGG-ID: GtaoVxW-OPqGPgA96HvLKw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3C0CA1955F3A; Fri, 13 Dec 2024 01:15:07 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 43B891956089; Fri, 13 Dec 2024 01:15:05 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 30/35] docs/qapi-domain: implement error context reporting fix Date: Thu, 12 Dec 2024 20:12:59 -0500 Message-ID: <20241213011307.2942030-31-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sphinx 5.3.0 to Sphinx 6.2.0 has a bug where nested content in an ObjectDescription content block has its error position reported incorrectly due to an oversight when they added nested section support to this directive. (This bug is present in Sphinx's own Python and C domains; test it yourself by creating a py:func directive and creating a syntax error in the directive's content block.) To avoid overriding and re-implementing the entirety of the run() method, a workaround is employed where we parse the content block ourselves in before_content(), then null the content block to make Sphinx's own parsing a no-op. Then, in transform_content (which occurs after Sphinx's nested parse), we simply swap our own parsed content tree back in for Sphinx's. It appears a little tricky, but it's the nicest solution I can find. Signed-off-by: John Snow --- docs/sphinx/qapi-domain.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 8dbf0ee5e70..7cbf12d93f7 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -21,8 +21,10 @@ from docutils import nodes from docutils.parsers.rst import directives +from docutils.statemachine import StringList from compat import keyword_node, nested_parse, space_node +import sphinx from sphinx import addnodes from sphinx.addnodes import desc_signature, pending_xref from sphinx.directives import ObjectDescription @@ -509,7 +511,29 @@ def _validate_field(self, field: nodes.field) -> None: ) logger.warning(msg, location=field) + def before_content(self) -> None: + # Work around a sphinx bug and parse the content ourselves. + self._temp_content = self.content + self._temp_offset = self.content_offset + self._temp_node = None + + if (5, 3, 0) <= sphinx.version_info[:3] < (6, 2, 0): + self._temp_node = addnodes.desc_content() + self.state.nested_parse( + self.content, self.content_offset, self._temp_node + ) + # Sphinx will try to parse the content block itself, + # Give it nothingness to parse instead. + self.content = StringList() + self.content_offset = 0 + def transform_content(self, contentnode: addnodes.desc_content) -> None: + # Sphinx workaround: Inject our parsed content and restore state. + if self._temp_node: + contentnode += self._temp_node.children + self.content = self._temp_content + self.content_offset = self._temp_offset + self._add_infopips(contentnode) self._merge_adjoining_field_lists(contentnode) From patchwork Fri Dec 13 01:13:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906264 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 024C7E77180 for ; Fri, 13 Dec 2024 01:18:09 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuHe-0001ND-3E; Thu, 12 Dec 2024 20:15:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH6-0000yR-S1 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:24 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuGw-0000vL-0Q for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052512; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cXzDH2S44TEsrk3c9xiUrSweb/whHKYC8mLrAY2rHQY=; b=PvsCfXf6qhaoQhVTHJK+lSzWdXD1Bc4hS9chFwANA1Ei29fFlZTEZPAwXbLb28Dh/ngGRs 1VXTaWJSb+9cLa0T79jmgKjg8svdANfpJ4k0/yZ8l8mSH1b+TBVX5mw62RHLKXmd5/whEt gXYzJJFx7lh2PwYE0DNknLr3hG4q2JI= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-149-hsmOC9QlN-qBOYJorDcc2A-1; Thu, 12 Dec 2024 20:15:10 -0500 X-MC-Unique: hsmOC9QlN-qBOYJorDcc2A-1 X-Mimecast-MFC-AGG-ID: hsmOC9QlN-qBOYJorDcc2A Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0912419560AF; Fri, 13 Dec 2024 01:15:10 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5655E1956096; Fri, 13 Dec 2024 01:15:08 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 31/35] docs/qapi-domain: collapsible branches Date: Thu, 12 Dec 2024 20:13:00 -0500 Message-ID: <20241213011307.2942030-32-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: John Snow --- docs/conf.py | 1 + docs/sphinx-static/theme_overrides.css | 10 ++ docs/sphinx/collapse.py | 200 +++++++++++++++++++++++++ docs/sphinx/qapi-domain.py | 157 +++++++++++++++---- 4 files changed, 341 insertions(+), 27 deletions(-) create mode 100644 docs/sphinx/collapse.py diff --git a/docs/conf.py b/docs/conf.py index bad35114351..7998d81f1d9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -61,6 +61,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + 'collapse', 'depfile', 'hxtool', 'kerneldoc', diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index 5ceb89eb9a8..2ba98d23bbd 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -296,3 +296,13 @@ dl.field-list > dt { dl.field-list > dd:not(:last-child) { padding-bottom: 1em; } + +dl.field-list > dd > details { + border-left: solid 5px #bcc6d2; +} + +dl.field-list > dd > details > summary { + background-color: #eaedf1; + color: black; + padding-left: 0.75em; +} diff --git a/docs/sphinx/collapse.py b/docs/sphinx/collapse.py new file mode 100644 index 00000000000..519f1f4b95b --- /dev/null +++ b/docs/sphinx/collapse.py @@ -0,0 +1,200 @@ +""" +Adds a collapsible section to an HTML page using a details_ element. + +.. _details: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details + +Modified (for formatting, vendoring and removing dependencies) from +sphinx_toolbox.collapse, originally by Dominic Davis-Foster + + +See https://github.com/sphinx-toolbox/sphinx-toolbox/tree/master + +""" + +# +# Copyright © 2021 Dominic Davis-Foster +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +# OR OTHER DEALINGS IN THE SOFTWARE. +# + +# stdlib +from typing import ( + Any, + ClassVar, + Dict, + Optional, + Sequence, +) + +# 3rd party +from docutils import nodes +from docutils.parsers.rst import directives +from docutils.parsers.rst.roles import set_classes + +from sphinx.application import Sphinx +from sphinx.util.docutils import SphinxDirective +from sphinx.writers.html import HTMLTranslator + + +__all__ = ( + "CollapseDirective", + "CollapseNode", + "visit_collapse_node", + "depart_collapse_node", + "setup", +) + + +def flag(argument: Any) -> bool: + """ + Check for a valid flag option (no argument) and return :py:obj:`True`. + + Used in the ``option_spec`` of directives. + + .. seealso:: + + :class:`docutils.parsers.rst.directives.flag`, which returns + :py:obj:`None` instead of :py:obj:`True`. + + :raises: :exc:`ValueError` if an argument is given. + """ + if argument and argument.strip(): + raise ValueError(f"No argument is allowed; {argument!r} supplied") + else: + return True + + +class CollapseDirective(SphinxDirective): + """ + A Sphinx directive to add a collapsible section to an HTML page + using a details_ element. + + .. _details: + https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details + """ + + final_argument_whitespace: ClassVar[bool] = True + has_content: ClassVar[bool] = True + + # The label + required_arguments: ClassVar[int] = 1 + + option_spec = { + "class": directives.class_option, + "name": directives.unchanged, + "open": flag, + } + + def run(self) -> Sequence[nodes.Node]: + """ + Process the content of the directive. + """ + + set_classes(self.options) + self.assert_has_content() + + text = "\n".join(self.content) + label = self.arguments[0] + + collapse_node = CollapseNode(text, label, **self.options) + + self.add_name(collapse_node) + + collapse_node["classes"].append(f"summary-{nodes.make_id(label)}") + + self.state.nested_parse( + self.content, self.content_offset, collapse_node + ) + + return [collapse_node] + + +class CollapseNode(nodes.Body, nodes.Element): + """ + Node that represents a collapsible section. + + :param rawsource: + :param label: + """ + + def __init__( + self, + rawsource: str = "", + label: Optional[str] = None, + *children: Any, + **attributes: Any, + ) -> None: + super().__init__(rawsource, *children, **attributes) + self.label = label + + +def visit_collapse_node(translator: HTMLTranslator, node: CollapseNode) -> None: + """ + Visit a :class:`~.CollapseNode`. + + :param translator: + :param node: The node being visited. + """ + + tag_parts = ["details"] + + if names := node.get("names", None): + tag_parts.append(f'name="{" ".join(names)}"') + + if classes := node.get("classes", None): + tag_parts.append(f'class="{" ".join(classes)}"') + + if node.attributes.get("open", False): + tag_parts.append("open") + + translator.body.append( + f"<{' '.join(tag_parts)}>\n{node.label}" + ) + translator.context.append("") + + +def depart_collapse_node( + translator: HTMLTranslator, node: CollapseNode +) -> None: + """ + Depart a :class:`~.CollapseNode`. + + :param translator: + :param node: The node being visited. + """ + translator.body.append(translator.context.pop()) + + +def setup(app: Sphinx) -> Dict[str, Any]: + """ + Setup :mod:`sphinx_toolbox.collapse`. + + :param app: The Sphinx application. + """ + app.add_directive("collapse", CollapseDirective) + app.add_node( + CollapseNode, + html=(visit_collapse_node, depart_collapse_node), + latex=(lambda *args, **kwargs: None, lambda *args, **kwargs: None), + ) + + return { + "parallel_read_safe": True, + "version": "3.5.0", + } diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 7cbf12d93f7..ee9b1d056ff 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -23,6 +23,7 @@ from docutils.parsers.rst import directives from docutils.statemachine import StringList +from collapse import CollapseNode from compat import keyword_node, nested_parse, space_node import sphinx from sphinx import addnodes @@ -466,10 +467,7 @@ def _validate_field(self, field: nodes.field) -> None: allowed_fields = set(self.env.app.config.qapi_allowed_fields) field_label = name.astext() - if ( - re.match(r"\[\S+ = \S+\]", field_label) - or field_label in allowed_fields - ): + if field_label == ":BRANCH:" or field_label in allowed_fields: # okie-dokey. branch entry or known good allowed name. return @@ -528,6 +526,8 @@ def before_content(self) -> None: self.content_offset = 0 def transform_content(self, contentnode: addnodes.desc_content) -> None: + self.content_node = contentnode + # Sphinx workaround: Inject our parsed content and restore state. if self._temp_node: contentnode += self._temp_node.children @@ -547,6 +547,66 @@ def transform_content(self, contentnode: addnodes.desc_content) -> None: assert isinstance(field, nodes.field) self._validate_field(field) + def after_content(self) -> None: + # Now that the DocFieldTransformer has been invoked in + # ObjectDescription.run, we can take our branch entries and + # extract their contents and inject them into the preceding + # field list body. + + # For example: + # + # Arguments: * lorem + # * ipsum + # :BRANCH: + # + # will be transformed into: + # + # Arguments: * lorem + # * ipsum + # + + branch_content: List[nodes.Node] = [] + insertion_field: Optional[nodes.field] = None + + def _inject( + field: Optional[nodes.field], content: List[nodes.Node] + ) -> None: + if not (field or content): + return + if not field: + print( + "ERROR: qapi:branch directive used without a preceding " + "Members/Arguments field; there's nowhere to inject the " + "branch members into!" + ) + return + _, body = _unpack_field(field) + body += content + + for child in self.content_node: + if isinstance(child, nodes.field_list): + delete_queue: List[nodes.field] = [] + for field in child.children: + assert isinstance(field, nodes.field) + name, body = _unpack_field(field) + if name.astext() == ":BRANCH:": + branch_content.extend(body.children) + delete_queue.append(field) + elif not branch_content: + insertion_field = field + else: + # Field is not a branch and branch_content is not empty; + # we should do the insertion here and now. + _inject(insertion_field, branch_content) + insertion_field = None + branch_content = [] + + # Delete any branches encountered thus far. + for field in delete_queue: + child.remove(field) + + _inject(insertion_field, branch_content) + def _toc_entry_name(self, sig_node: desc_signature) -> str: # This controls the name in the TOC and on the sidebar. @@ -770,14 +830,27 @@ def run(self) -> List[Node]: class Branch(SphinxDirective): """ - Nested directive which only serves to introduce temporary - metadata but return its parsed content nodes unaltered otherwise. + A nested directive to document union Branches. - Technically, you can put whatever you want in here, but doing so may - prevent proper merging of adjacent field lists. + This directive should contain at most one type of semantic/grouped + field list type, either "memb" or "arg". """ - doc_field_types: List[Field] = [] + # The :BRANCH: name is a placeholder. You can probably get a + # legitimate field list with this name if you try hard + # enough, but it should be difficult to do by accident. + doc_field_types: List[Field] = [ + # :arg type name: descr + # :memb type name: descr + QAPITypedField( + "branch-arg-or-memb", + label=":BRANCH:", + names=("arg", "memb"), + typerolename="type", + can_collapse=False, + ), + ] + has_content = True required_arguments = 2 optional_arguments = 0 @@ -799,29 +872,59 @@ def run(self) -> list[Node]: discrim = self.arguments[0].strip() value = self.arguments[1].strip() - # The label name is dynamically generated per-instance instead - # of per-class to incorporate the branch conditions as a label - # name. - self.doc_field_types = [ - # :arg type name: descr - # :memb type name: descr - QAPITypedField( - "branch-arg-or-memb", - label=f"[{discrim} = {value}]", - # In a branch, we don't actually use the name of the - # field name to generate the label; so allow either-or. - names=("arg", "memb"), - typerolename="type", - ), - ] - - content_node: addnodes.desc_content = addnodes.desc_content() + content_node = addnodes.desc_content() nested_parse(self, content_node) # DocFieldTransformer usually expects ObjectDescription, but... quack! transformer = DocFieldTransformer(quack(ObjectDescription, self)) transformer.transform_all(content_node) - return content_node.children + if not content_node.children: + # Empty branch - it happens. Squelch it. + return [] + + # Now, we're gonna do some surgery. + # + # We're going to find any field lists that contain members/args + # and extract the transformed content from that field list, + # while deleting the field list itself - to avoid having nested + # field lists for branches. + + replacements = [] + for child in content_node: + if isinstance(child, nodes.field_list): + if len(child.children) != 1: + # We're only interested in field lists with one field; + # since these are the semantically grouped/formatted bits. + continue + + field = child.children[0] + assert isinstance(field, nodes.field) + field_name, field_body = _unpack_field(field) + + if field_name.astext() == ":BRANCH:": + replacements.append((child, field_body)) + + # Delete grouped field lists, replacing them with just their content; + # after field transformation, this should be a list. + for child, field_body in replacements: + child.replace_self(field_body.children) + + # Wrap the entire contents up in a collapsible node + collapse_node = CollapseNode( + "", f"When {discrim} is {value}: ...", *content_node.children + ) + + # Then wrap it all back up in a new field list. + new_content = nodes.field_list( + "", + nodes.field( + "", + nodes.field_name("", ":BRANCH:"), + nodes.field_body("", collapse_node), + ), + ) + + return [new_content] class QAPIIndex(Index): From patchwork Fri Dec 13 01:13:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906269 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BECEAE7717F for ; Fri, 13 Dec 2024 01:18:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuHd-00017z-Ue; Thu, 12 Dec 2024 20:15:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH6-0000yW-SP for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:24 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH0-0000vv-29 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052516; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E2uBLnCFk7cw9O+LvbpeL9YtAqyFV9HBoqcOf2eGrOU=; b=Qv/3W8XVMBQW5Wea2zIvnEcWa3qzcEa0c2h4N5a+sqDsI8+mohSoj8HPUcnKkZZ1C9GGbB vzR9wFd8eXq9HvhHsvY2vKZwZOj4eBftgMuaxchAOuwG6ECxJiJjZ0oHAkUCc47rRjq7+b HUryIpyMTOzYV48/k7ogdPAVeohfiz4= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-675-0EitUavIPSe0ikg6VNw1Qw-1; Thu, 12 Dec 2024 20:15:14 -0500 X-MC-Unique: 0EitUavIPSe0ikg6VNw1Qw-1 X-Mimecast-MFC-AGG-ID: 0EitUavIPSe0ikg6VNw1Qw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8BA4F19560B3; Fri, 13 Dec 2024 01:15:13 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CD2BF1956086; Fri, 13 Dec 2024 01:15:10 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 32/35] WIP: 3.x - XREF Date: Thu, 12 Dec 2024 20:13:01 -0500 Message-ID: <20241213011307.2942030-33-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: John Snow --- docs/sphinx/compat.py | 114 +++++++++++++++++++- docs/sphinx/qapi-domain.py | 207 ++++++++++++------------------------- 2 files changed, 179 insertions(+), 142 deletions(-) diff --git a/docs/sphinx/compat.py b/docs/sphinx/compat.py index 28cb39161fe..657c05a81a4 100644 --- a/docs/sphinx/compat.py +++ b/docs/sphinx/compat.py @@ -2,14 +2,32 @@ Sphinx cross-version compatibility goop """ -from typing import Callable +import re +from typing import ( + Any, + Callable, + Optional, + Type, +) +from docutils import nodes from docutils.nodes import Element, Node, Text import sphinx from sphinx import addnodes -from sphinx.util.docutils import SphinxDirective, switch_source_input +from sphinx.environment import BuildEnvironment +from sphinx.roles import XRefRole +from sphinx.util import docfields +from sphinx.util.docutils import ( + ReferenceRole, + SphinxDirective, + switch_source_input, +) from sphinx.util.nodes import nested_parse_with_titles +from sphinx.util.typing import TextlikeNode + + +MAKE_XREF_WORKAROUND = sphinx.version_info[:3] < (4, 1, 0) space_node: Callable[[str], Node] @@ -46,3 +64,95 @@ def nested_parse(directive: SphinxDirective, content_node: Element) -> None: nested_parse_with_titles( directive.state, directive.content, content_node ) + + +class CompatFieldMixin: + """ + Compatibility workaround for Sphinx versions prior to 4.1.0. + + Older sphinx versions do not use the domain's XRefRole for parsing + and formatting cross-references, so we need to perform this magick + ourselves to avoid needing to write the parser/formatter in two + separate places. + + This workaround isn't brick-for-brick compatible with modern Sphinx + versions, because we do not have access to the parent directive's + state during this parsing like we do in more modern versions. + + It's no worse than what pre-Sphinx 4.1.0 does, so... oh well! + """ + + def make_xref( + self, + rolename: str, + domain: str, + target: str, + innernode: Type[TextlikeNode] = addnodes.literal_emphasis, + contnode: Optional[Node] = None, + env: Optional[BuildEnvironment] = None, + *args: Any, + **kwargs: Any, + ) -> Node: + print("Using compat make_xref") + + assert env + if not rolename: + return contnode or innernode(target, target) + + # Get the role instance, but don't *execute it* - we lack the + # correct state to do so. Instead, we'll just use its public + # methods to do our reference formatting, and emulate the rest. + role = env.get_domain(domain).roles[rolename] + assert isinstance(role, XRefRole) + + # XRefRole features not supported by this compatibility shim; + # these were not supported in Sphinx 3.x either, so nothing of + # value is really lost. + assert not target.startswith("!") + assert not re.match(ReferenceRole.explicit_title_re, target) + assert not role.lowercase + assert not role.fix_parens + + # Code below based mostly on sphinx.roles.XRefRole; run() and + # create_xref_node() + options = { + "refdoc": env.docname, + "refdomain": domain, + "reftype": rolename, + "refexplicit": False, + "refwarn": role.warn_dangling, + } + refnode = role.nodeclass(target, **options) + title, target = role.process_link(env, refnode, False, target, target) + refnode["reftarget"] = target + classes = ["xref", domain, f"{domain}-{rolename}"] + refnode += role.innernodeclass(target, title, classes=classes) + result_nodes, messages = role.result_nodes( + None, # FIXME - normally self.inliner.document ... + env, + refnode, + is_ref=True, + ) + return nodes.inline(target, "", *result_nodes) + + +class CompatField(CompatFieldMixin, docfields.Field): + pass + + +class CompatGroupedField(CompatFieldMixin, docfields.GroupedField): + pass + + +class CompatTypedField(CompatFieldMixin, docfields.TypedField): + pass + + +if not MAKE_XREF_WORKAROUND: + Field = docfields.Field + GroupedField = docfields.GroupedField + TypedField = docfields.TypedField +else: + Field = CompatField + GroupedField = CompatGroupedField + TypedField = CompatTypedField diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index ee9b1d056ff..ebdf9074391 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -24,7 +24,14 @@ from docutils.statemachine import StringList from collapse import CollapseNode -from compat import keyword_node, nested_parse, space_node +from compat import ( + Field, + GroupedField, + TypedField, + keyword_node, + nested_parse, + space_node, +) import sphinx from sphinx import addnodes from sphinx.addnodes import desc_signature, pending_xref @@ -38,24 +45,18 @@ from sphinx.locale import _, __ from sphinx.roles import XRefRole from sphinx.util import logging -from sphinx.util.docfields import ( - DocFieldTransformer, - Field, - GroupedField, - TypedField, -) +from sphinx.util.docfields import DocFieldTransformer from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import make_id, make_refnode if TYPE_CHECKING: from docutils.nodes import Element, Node - from docutils.parsers.rst.states import Inliner from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec, TextlikeNode + from sphinx.util.typing import OptionSpec logger = logging.getLogger(__name__) @@ -82,111 +83,8 @@ class ObjectEntry(NamedTuple): aliased: bool -class QAPIXrefMixin: - def make_xref( - self, - rolename: str, - domain: str, - target: str, - innernode: type[TextlikeNode] = nodes.literal, - contnode: Optional[Node] = None, - env: Optional[BuildEnvironment] = None, - inliner: Optional[Inliner] = None, - location: Optional[Node] = None, - ) -> Node: - # make_xref apparently has a mode of operation where the inliner - # class argument is passed to the role object - # (e.g. QAPIXRefRole) to construct the final result; passing - # inliner = location = None forces it into its legacy mode where - # it returns a pending_xref node instead. - # (This is how the built-in Python domain behaves.) - result = super().make_xref( # type: ignore[misc] - rolename, - domain, - target, - innernode=innernode, - contnode=contnode, - env=env, - inliner=None, - location=None, - ) - if isinstance(result, pending_xref): - assert env is not None - # Add domain-specific context information to the pending reference. - result["refspecific"] = True - result["qapi:module"] = env.ref_context.get("qapi:module") - - assert isinstance(result, nodes.Node) - return result - - def make_xrefs( - self, - rolename: str, - domain: str, - target: str, - innernode: type[TextlikeNode] = nodes.literal, - contnode: Optional[Node] = None, - env: Optional[BuildEnvironment] = None, - inliner: Optional[Inliner] = None, - location: Optional[Node] = None, - ) -> list[Node]: - # Note: this function is called on up to three fields of text: - # (1) The field name argument (e.g. member/arg name) - # (2) The field name type (e.g. member/arg type) - # (3) The field *body* text, for Fields that do not take arguments. - - list_type = False - optional = False - - # If the rolename is qapi:type, we know we are processing a type - # and not an arg/memb name or field body text. - if rolename == "type": - # force the innernode class to be a literal. - innernode = nodes.literal - - # Type names that end with "?" are considered Optional - # arguments and should be documented as such, but it's not - # part of the xref itself. - if target.endswith("?"): - optional = True - target = target[:-1] - - # Type names wrapped in brackets denote lists. strip the - # brackets and remember to add them back later. - if target.startswith("[") and target.endswith("]"): - list_type = True - target = target[1:-1] - - # When processing Fields with bodyrolename="type", contnode - # will be present, which indicates that the body has already - # been parsed into nodes. We don't want that, actually: - # we'll re-create our own nodes for it. - contnode = None - - results = [] - result = self.make_xref( - rolename, - domain, - target, - innernode, - contnode, - env, - inliner, - location, - ) - results.append(result) - - if list_type: - results.insert(0, nodes.literal("[", "[")) - results.append(nodes.literal("]", "]")) - if optional: - results.append(nodes.Text(", ")) - results.append(nodes.emphasis("?", "optional")) - - return results - - class QAPIXRefRole(XRefRole): + def process_link( self, env: BuildEnvironment, @@ -196,34 +94,63 @@ def process_link( target: str, ) -> tuple[str, str]: refnode["qapi:module"] = env.ref_context.get("qapi:module") - if not has_explicit_title: - title = title.lstrip(".") # only has a meaning for the target - target = target.lstrip("~") # only has a meaning for the title - # if the first character is a tilde, don't display the module - # parts of the contents - if title[0:1] == "~": - title = title[1:] - dot = title.rfind(".") - if dot != -1: - title = title[dot + 1 :] - # if the first character is a dot, search more specific namespaces first - # else search builtins first - if target[0:1] == ".": + + # Cross-references that begin with a tilde adjust the title to + # only show the reference without a leading module, even if one + # was provided. This is a Sphinx-standard syntax; give it + # priority over QAPI-specific type markup below. + hide_module = False + if target.startswith("~"): + hide_module = True target = target[1:] - refnode["refspecific"] = True + + # Type names that end with "?" are considered optional + # arguments and should be documented as such, but it's not + # part of the xref itself. + if target.endswith("?"): + refnode["qapi:optional"] = True + target = target[:-1] + + # Type names wrapped in brackets denote lists. strip the + # brackets and remember to add them back later. + if target.startswith("[") and target.endswith("]"): + refnode["qapi:array"] = True + target = target[1:-1] + + if has_explicit_title: + # Don't mess with the title at all if it was explicitly set. + # Explicit title syntax for references is e.g. + # :qapi:type:`target ` + # and this explicit title overrides everything else here. + return title, target + + title = target + if hide_module: + title = target.split(".")[-1] + return title, target + def result_nodes( + self, + document: nodes.document, + env: BuildEnvironment, + node: Element, + is_ref: bool, + ) -> Tuple[List[nodes.Node], List[nodes.system_message]]: -class QAPIGroupedField(QAPIXrefMixin, GroupedField): - pass + # node here is the pending_xref node (or whatever nodeclass was + # configured at XRefRole class instantiation time). + results: List[nodes.Node] = [node] + if node.get("qapi:array"): + results.insert(0, nodes.literal("[", "[")) + results.append(nodes.literal("]", "]")) -class QAPITypedField(QAPIXrefMixin, TypedField): - pass + if node.get("qapi:optional"): + results.append(nodes.Text(", ")) + results.append(nodes.emphasis("?", "optional")) - -class QAPIField(QAPIXrefMixin, Field): - pass + return results, [] def since_validator(param: str) -> str: @@ -633,7 +560,7 @@ class QAPICommand(QAPIObject): doc_field_types.extend( [ # :arg TypeName ArgName: descr - QAPITypedField( + TypedField( "argument", label=_("Arguments"), names=("arg",), @@ -648,7 +575,7 @@ class QAPICommand(QAPIObject): has_arg=False, ), # :returns TypeName: descr - QAPIGroupedField( + GroupedField( "returnvalue", label=_("Returns"), rolename="type", @@ -656,7 +583,7 @@ class QAPICommand(QAPIObject): can_collapse=True, ), # :returns-nodesc: TypeName - QAPIField( + Field( "returnvalue", label=_("Returns"), names=("returns-nodesc",), @@ -691,7 +618,7 @@ class QAPIAlternate(QAPIObject): doc_field_types.extend( [ # :choice type name: descr - QAPITypedField( + TypedField( "choice", label=_("Choices"), names=("choice",), @@ -709,7 +636,7 @@ class QAPIObjectWithMembers(QAPIObject): doc_field_types.extend( [ # :member type name: descr - QAPITypedField( + TypedField( "member", label=_("Members"), names=("memb",), @@ -842,7 +769,7 @@ class Branch(SphinxDirective): doc_field_types: List[Field] = [ # :arg type name: descr # :memb type name: descr - QAPITypedField( + TypedField( "branch-arg-or-memb", label=":BRANCH:", names=("arg", "memb"), From patchwork Fri Dec 13 01:13:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906295 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C64D2E7717F for ; Fri, 13 Dec 2024 01:19:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuI0-00024i-Uy; Thu, 12 Dec 2024 20:16:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH6-0000wI-KE for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:24 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH4-0000wR-I5 for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052521; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2Us7t8EzSXoOEU6CCGbRd6lLvImyt92QDEHdxf45t34=; b=LjrkIwUQ1RIJNYThLKUN19Xzo9bhtdtfEDYzCE+YSmNLxPe013NLzGwdUFn+T0kPwBjBU9 FyrQvv6cOGKBYEWP/13RK1Gf2rqwBTMMmONIUHg/81WBOAmnHacl35mM55AkkXev6e/Jkf jkABZKvJCe/3oaZ0WkUCPr0wcB5JeBc= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-584-xabWTRepOqCJF9arhJUp_w-1; Thu, 12 Dec 2024 20:15:17 -0500 X-MC-Unique: xabWTRepOqCJF9arhJUp_w-1 X-Mimecast-MFC-AGG-ID: xabWTRepOqCJF9arhJUp_w Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 140ED19560A3; Fri, 13 Dec 2024 01:15:16 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 16F681956086; Fri, 13 Dec 2024 01:15:13 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 33/35] WIP: 3.x ParserFix Date: Thu, 12 Dec 2024 20:13:02 -0500 Message-ID: <20241213011307.2942030-34-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: John Snow --- docs/sphinx/compat.py | 33 +++++++++++++++++++++++++++++++++ docs/sphinx/qapi-domain.py | 32 +++++++------------------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/docs/sphinx/compat.py b/docs/sphinx/compat.py index 657c05a81a4..5126b450a5f 100644 --- a/docs/sphinx/compat.py +++ b/docs/sphinx/compat.py @@ -12,9 +12,11 @@ from docutils import nodes from docutils.nodes import Element, Node, Text +from docutils.statemachine import StringList import sphinx from sphinx import addnodes +from sphinx.directives import ObjectDescription from sphinx.environment import BuildEnvironment from sphinx.roles import XRefRole from sphinx.util import docfields @@ -28,6 +30,7 @@ MAKE_XREF_WORKAROUND = sphinx.version_info[:3] < (4, 1, 0) +SOURCE_LOCATION_FIX = (5, 3, 0) <= sphinx.version_info[:3] < (6, 2, 0) space_node: Callable[[str], Node] @@ -156,3 +159,33 @@ class CompatTypedField(CompatFieldMixin, docfields.TypedField): Field = CompatField GroupedField = CompatGroupedField TypedField = CompatTypedField + + +class ParserFix(ObjectDescription): + + _temp_content: StringList + _temp_offset: int + _temp_node: Optional[addnodes.desc_content] + + def before_content(self) -> None: + # Work around a sphinx bug and parse the content ourselves. + self._temp_content = self.content + self._temp_offset = self.content_offset + self._temp_node = None + + if SOURCE_LOCATION_FIX: + self._temp_node = addnodes.desc_content() + self.state.nested_parse( + self.content, self.content_offset, self._temp_node + ) + # Sphinx will try to parse the content block itself, + # Give it nothingness to parse instead. + self.content = StringList() + self.content_offset = 0 + + def transform_content(self, contentnode: addnodes.desc_content) -> None: + # Sphinx workaround: Inject our parsed content and restore state. + if self._temp_node: + contentnode += self._temp_node.children + self.content = self._temp_content + self.content_offset = self._temp_offset diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index ebdf9074391..00d32d44e1d 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -21,18 +21,17 @@ from docutils import nodes from docutils.parsers.rst import directives -from docutils.statemachine import StringList from collapse import CollapseNode from compat import ( Field, GroupedField, + ParserFix, TypedField, keyword_node, nested_parse, space_node, ) -import sphinx from sphinx import addnodes from sphinx.addnodes import desc_signature, pending_xref from sphinx.directives import ObjectDescription @@ -170,7 +169,7 @@ def since_validator(param: str) -> str: Signature = str -class QAPIObject(ObjectDescription[Signature]): +class QAPIObject(ParserFix, ObjectDescription[Signature]): """ Description of a generic QAPI object. @@ -436,31 +435,14 @@ def _validate_field(self, field: nodes.field) -> None: ) logger.warning(msg, location=field) - def before_content(self) -> None: - # Work around a sphinx bug and parse the content ourselves. - self._temp_content = self.content - self._temp_offset = self.content_offset - self._temp_node = None - - if (5, 3, 0) <= sphinx.version_info[:3] < (6, 2, 0): - self._temp_node = addnodes.desc_content() - self.state.nested_parse( - self.content, self.content_offset, self._temp_node - ) - # Sphinx will try to parse the content block itself, - # Give it nothingness to parse instead. - self.content = StringList() - self.content_offset = 0 - def transform_content(self, contentnode: addnodes.desc_content) -> None: + # This hook runs after before_content and the nested parse, but + # before the DocFieldTransformer is executed. + super().transform_content(contentnode) + + # Bookmark this content_node for later use in after_content(). self.content_node = contentnode - # Sphinx workaround: Inject our parsed content and restore state. - if self._temp_node: - contentnode += self._temp_node.children - self.content = self._temp_content - self.content_offset = self._temp_offset - self._add_infopips(contentnode) self._merge_adjoining_field_lists(contentnode) From patchwork Fri Dec 13 01:13:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906259 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 08D79E77180 for ; Fri, 13 Dec 2024 01:16:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuHz-0001s6-M2; Thu, 12 Dec 2024 20:16:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH7-00010X-Sb for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:28 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH6-0000wT-5C for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052522; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UI8k4bLF/f2KJ4I9nTVpY7xzkypAiwueEZlTj/biSjw=; b=Gs/WAa+X8YKGp8Q2XSCIoADx7nyCfiW7zavqZWzqGRbLWHoYVXI5jFaSrUoQckUpQw+Ty4 wlcau8MWvZTVvzliBG/0P584xW1m2KRje/AYwXs2QRDVLTCVpI3nC1iOz4S6yNL3m3hPMm MLSfEuZk//fPUi8b/pPrgccRZv4+3cs= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-652-pT8rdSG5M7CZRejPCBafhA-1; Thu, 12 Dec 2024 20:15:18 -0500 X-MC-Unique: pT8rdSG5M7CZRejPCBafhA-1 X-Mimecast-MFC-AGG-ID: pT8rdSG5M7CZRejPCBafhA Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A5B5E1956096; Fri, 13 Dec 2024 01:15:17 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 513311956086; Fri, 13 Dec 2024 01:15:16 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 34/35] WIP: 3.x ObjectDesc compat Date: Thu, 12 Dec 2024 20:13:03 -0500 Message-ID: <20241213011307.2942030-35-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: John Snow --- docs/sphinx/compat.py | 7 +++++++ docs/sphinx/qapi-domain.py | 9 +++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/sphinx/compat.py b/docs/sphinx/compat.py index 5126b450a5f..b2d2d1be403 100644 --- a/docs/sphinx/compat.py +++ b/docs/sphinx/compat.py @@ -33,15 +33,22 @@ SOURCE_LOCATION_FIX = (5, 3, 0) <= sphinx.version_info[:3] < (6, 2, 0) +# Alias for the return of QAPIObject.handle_signature(), which is used +# in several places. (In the Python domain, this type is Tuple[str, +# str] instead.) +Signature = str + space_node: Callable[[str], Node] keyword_node: Callable[[str, str], Node] if sphinx.version_info[:3] >= (4, 0, 0): space_node = addnodes.desc_sig_space keyword_node = addnodes.desc_sig_keyword + ObjectDesc = ObjectDescription[Signature] else: space_node = Text keyword_node = addnodes.desc_annotation + ObjectDesc = ObjectDescription def nested_parse(directive: SphinxDirective, content_node: Element) -> None: diff --git a/docs/sphinx/qapi-domain.py b/docs/sphinx/qapi-domain.py index 00d32d44e1d..fcda281d45e 100644 --- a/docs/sphinx/qapi-domain.py +++ b/docs/sphinx/qapi-domain.py @@ -26,7 +26,9 @@ from compat import ( Field, GroupedField, + ObjectDesc, ParserFix, + Signature, TypedField, keyword_node, nested_parse, @@ -164,12 +166,7 @@ def since_validator(param: str) -> str: return param -# 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 - - -class QAPIObject(ParserFix, ObjectDescription[Signature]): +class QAPIObject(ParserFix, ObjectDesc): """ Description of a generic QAPI object. From patchwork Fri Dec 13 01:13:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 13906298 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 80968E7717F for ; Fri, 13 Dec 2024 01:19:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tLuHx-0001dn-40; Thu, 12 Dec 2024 20:16:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH7-00010W-QI for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:28 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tLuH6-0000wa-7S for qemu-devel@nongnu.org; Thu, 12 Dec 2024 20:15:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1734052523; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IvKWWbx3VuNs7SmScGhEYzPYbPPGlSjOuN/y1eaKEhg=; b=ShqThwTlGh5ZpFnxZ5EW31y3beHdV5i4De221SZWVrsoEOr3JD7xxa6UWwNdlWWiCnGjER ygJo8884RgVLFC3p1abcBibHFixg2/MNrXREq7MjIwjQkZaFIgwW/n9k1ZBJxXxPaNUwYu D8CJbImiTCmIeK/Rt68P/JUE30ejUjU= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-145-J_qb6-14O4G3wfug0f4x-A-1; Thu, 12 Dec 2024 20:15:21 -0500 X-MC-Unique: J_qb6-14O4G3wfug0f4x-A-1 X-Mimecast-MFC-AGG-ID: J_qb6-14O4G3wfug0f4x-A Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4ED1B1955D47; Fri, 13 Dec 2024 01:15:20 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.22]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E07CC1956089; Fri, 13 Dec 2024 01:15:17 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Cc: Michael Roth , Markus Armbruster , Peter Maydell , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , Victor Toso de Carvalho , Paolo Bonzini , John Snow Subject: [RFC PATCH v2 35/35] WIP: 3.x css theming for missing xref Date: Thu, 12 Dec 2024 20:13:04 -0500 Message-ID: <20241213011307.2942030-36-jsnow@redhat.com> In-Reply-To: <20241213011307.2942030-1-jsnow@redhat.com> References: <20241213011307.2942030-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.496, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: John Snow --- docs/sphinx-static/theme_overrides.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css index 2ba98d23bbd..0cab9bd8eb9 100644 --- a/docs/sphinx-static/theme_overrides.css +++ b/docs/sphinx-static/theme_overrides.css @@ -306,3 +306,9 @@ dl.field-list > dd > details > summary { color: black; padding-left: 0.75em; } + +/* missing field xrefs */ +.rst-content *:not(a) > code.xref { + font-weight: 400; + color: #333333; +}