get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2227547/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2227547,
    "url": "http://patchwork.ozlabs.org/api/patches/2227547/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260423220022.2180059-8-jsnow@redhat.com/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260423220022.2180059-8-jsnow@redhat.com>",
    "list_archive_url": null,
    "date": "2026-04-23T22:00:16",
    "name": "[07/12] qapi/docs: add \"Intro\" section parsing",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "a335fc2cc68fccccc0db709c664921cf83d6160f",
    "submitter": {
        "id": 64343,
        "url": "http://patchwork.ozlabs.org/api/people/64343/?format=api",
        "name": "John Snow",
        "email": "jsnow@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260423220022.2180059-8-jsnow@redhat.com/mbox/",
    "series": [
        {
            "id": 501255,
            "url": "http://patchwork.ozlabs.org/api/series/501255/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501255",
            "date": "2026-04-23T22:00:11",
            "name": "qapi: add formal \"intro\" section",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501255/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2227547/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2227547/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=dR83mil9;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g1qnV2p0Rz1yDD\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 08:02:06 +1000 (AEST)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wG26X-0005jN-CK; Thu, 23 Apr 2026 18:01:01 -0400",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <jsnow@redhat.com>) id 1wG26U-0005if-OD\n for qemu-devel@nongnu.org; Thu, 23 Apr 2026 18:00:58 -0400",
            "from us-smtp-delivery-124.mimecast.com ([170.10.129.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <jsnow@redhat.com>) id 1wG26S-0005oL-Q1\n for qemu-devel@nongnu.org; Thu, 23 Apr 2026 18:00:58 -0400",
            "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-187-YgNc6UtWOX6AobcM3Y2MVQ-1; Thu,\n 23 Apr 2026 18:00:52 -0400",
            "from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 4E78E18004AD; Thu, 23 Apr 2026 22:00:51 +0000 (UTC)",
            "from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.64.143])\n by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id 10D393007572; Thu, 23 Apr 2026 22:00:47 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776981656;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=GJwsAHqVNyKJNf+9t90voerKf684uX/eo0z3dIcCjdA=;\n b=dR83mil9PjrH4NVqQS9GpPB0Gg6HFBzRKWOaZhECPK26IPLIx0JN6jAOHA6nRErIsQ7/b/\n 6tR3RmSc55X21qwqw/iusOEecNTFfGdeIX5/rztAeLB7ytRPovdRKHb9WI/cSZ31NWu9Q3\n APfx3/O//bkaOtn0tuUtekrGMSl5RO8=",
        "X-MC-Unique": "YgNc6UtWOX6AobcM3Y2MVQ-1",
        "X-Mimecast-MFC-AGG-ID": "YgNc6UtWOX6AobcM3Y2MVQ_1776981651",
        "From": "John Snow <jsnow@redhat.com>",
        "To": "qemu-devel@nongnu.org",
        "Cc": "Igor Mammedov <imammedo@redhat.com>,\n Mauro Carvalho Chehab <mchehab+huawei@kernel.org>,\n \"Michael S. Tsirkin\" <mst@redhat.com>, Michael Roth <michael.roth@amd.com>,\n Markus Armbruster <armbru@redhat.com>, Ani Sinha <anisinha@redhat.com>,\n Gerd Hoffmann <kraxel@redhat.com>, Eric Blake <eblake@redhat.com>,\n Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>, =?utf-8?q?Philippe_Ma?=\n\t=?utf-8?q?thieu-Daud=C3=A9?= <philmd@linaro.org>, =?utf-8?q?Marc-Andr=C3=A9?=\n\t=?utf-8?q?_Lureau?= <marcandre.lureau@redhat.com>,\n Richard Henderson <richard.henderson@linaro.org>,\n Paolo Bonzini <pbonzini@redhat.com>,\n Peter Maydell <peter.maydell@linaro.org>, John Snow <jsnow@redhat.com>",
        "Subject": "[PATCH 07/12] qapi/docs: add \"Intro\" section parsing",
        "Date": "Thu, 23 Apr 2026 18:00:16 -0400",
        "Message-ID": "<20260423220022.2180059-8-jsnow@redhat.com>",
        "In-Reply-To": "<20260423220022.2180059-1-jsnow@redhat.com>",
        "References": "<20260423220022.2180059-1-jsnow@redhat.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.4",
        "Received-SPF": "pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com",
        "X-Spam_score_int": "-20",
        "X-Spam_score": "-2.1",
        "X-Spam_bar": "--",
        "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001,\n SPF_HELO_PASS=-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": "qemu development <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "Add parsing for explicit Intro section syntax.\n\nA side effect of this patch is that we will always create an empty Intro\nsection, similar to how we used to have an empty Plain section. The\ntests are adjusted accordingly, rendered document output does not change\nat all.\n\nSigned-off-by: John Snow <jsnow@redhat.com>\n---\n docs/devel/qapi-code-gen.rst            | 17 +++++----\n scripts/qapi/parser.py                  | 47 ++++++++++++++++++-------\n tests/qapi-schema/doc-good.out          | 18 ++++++++++\n tests/qapi-schema/doc-missing-colon.err |  2 +-\n 4 files changed, 64 insertions(+), 20 deletions(-)",
    "diff": "diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst\nindex 3a632b4a648..a8175934d52 100644\n--- a/docs/devel/qapi-code-gen.rst\n+++ b/docs/devel/qapi-code-gen.rst\n@@ -862,7 +862,7 @@ documentation comment.\n If the documentation comment starts like ::\n \n     ##\n-    # @SYMBOL:\n+    # @SYMBOL: [...]\n \n it documents the definition of SYMBOL, else it's free-form\n documentation.\n@@ -984,11 +984,11 @@ definition it documents.\n When documentation is required (see pragma_ 'doc-required'), every\n definition must have documentation.\n \n-Definition documentation starts with a line naming the definition,\n-followed by an optional overview, a description of each argument (for\n-commands and events), member (for structs and unions), branch (for\n-alternates), or value (for enums), a description of each feature (if\n-any), and finally optional tagged sections.\n+Definition documentation starts with a description naming the definition\n+with an optional overview, a description of each argument (for commands\n+and events), member (for structs and unions), branch (for alternates),\n+or value (for enums), a description of each feature (if any), and\n+finally optional tagged sections.\n \n Descriptions start with '\\@name:'.  The description text must be\n indented like this::\n@@ -996,6 +996,11 @@ indented like this::\n  # @name: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed\n  #     do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n \n+Definition descriptions are special: the optional introductory overview\n+describing the definition will not be inlined when referenced by other\n+definitions (such as when using 'base' to include members from another\n+definition), while other descriptions and tagged sections will be.\n+\n .. FIXME The parser accepts these things in almost any order.\n \n .. FIXME union branches should be described, too.\ndiff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py\nindex 6612f471bb8..c23fd26aaa7 100644\n--- a/scripts/qapi/parser.py\n+++ b/scripts/qapi/parser.py\n@@ -24,6 +24,7 @@\n     Match,\n     Optional,\n     Set,\n+    Tuple,\n     Union,\n )\n \n@@ -524,6 +525,30 @@ def get_doc_paragraph(self, doc: 'QAPIDoc') -> Optional[str]:\n                 return line\n             doc.append_line(line)\n \n+    def _get_doc_intro(\n+        self,\n+        line: str,\n+        info: QAPISourceInfo\n+    ) -> Tuple['QAPIDoc', Optional[str]]:\n+        match = self._match_at_name_colon(line)\n+        if not match:\n+            raise QAPIParseError(self, \"@name must end with ':'\")\n+\n+        # Invalid names are not checked here, but the name\n+        # provided *must* match the following definition,\n+        # which *is* validated in expr.py.\n+        symbol = match.group(1)\n+        if not symbol:\n+            raise QAPIParseError(self, \"name required after '@'\")\n+        doc = QAPIDoc(info, symbol)\n+\n+        doc.ensure_untagged_section(info, QAPIDoc.Kind.INTRO)\n+        text = line[match.end():]\n+        if text:\n+            doc.append_line(text)\n+\n+        return doc, self.get_doc_indented(doc)\n+\n     def get_doc(self) -> 'QAPIDoc':\n         if self.val != '##':\n             raise QAPIParseError(\n@@ -532,18 +557,9 @@ def get_doc(self) -> 'QAPIDoc':\n         self.accept(False)\n         line = self.get_doc_line()\n         if line is not None and line.startswith('@'):\n+\n             # Definition documentation\n-            if not line.endswith(':'):\n-                raise QAPIParseError(self, \"line should end with ':'\")\n-            # Invalid names are not checked here, but the name\n-            # provided *must* match the following definition,\n-            # which *is* validated in expr.py.\n-            symbol = line[1:-1]\n-            if not symbol:\n-                raise QAPIParseError(self, \"name required after '@'\")\n-            doc = QAPIDoc(info, symbol)\n-            self.accept(False)\n-            line = self.get_doc_line()\n+            doc, line = self._get_doc_intro(line, info)\n             no_more_args = False\n \n             while line is not None:\n@@ -751,8 +767,13 @@ def end(self) -> None:\n                 raise QAPISemError(\n                     section.info, \"text required after '%s:'\" % section.kind)\n \n-    def ensure_untagged_section(self, info: QAPISourceInfo) -> None:\n-        kind = QAPIDoc.Kind.PLAIN\n+    def ensure_untagged_section(\n+        self,\n+        info: QAPISourceInfo,\n+        kind: Optional['QAPIDoc.Kind'] = None,\n+    ) -> None:\n+        if kind is None:\n+            kind = QAPIDoc.Kind.PLAIN\n \n         if self.all_sections and self.all_sections[-1].kind == kind:\n             # extend current section\ndiff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out\nindex 6fcc8175cfe..bc89853765f 100644\n--- a/tests/qapi-schema/doc-good.out\n+++ b/tests/qapi-schema/doc-good.out\n@@ -106,6 +106,8 @@ Examples:\n - *verbatim*\n - {braces}\n doc symbol=Enum\n+    section=Intro\n+\n     arg=one\n The _one_ {and only}, description on the same line\n     arg=two\n@@ -117,10 +119,14 @@ a member feature\n     section=Plain\n @two is undocumented\n doc symbol=Base\n+    section=Intro\n+\n     arg=base1\n  description starts on a new line,\n  minimally indented\n doc symbol=Variant1\n+    section=Intro\n+\n     section=Plain\n A paragraph\n \n@@ -134,10 +140,16 @@ a feature\n     feature=member-feat\n a member feature\n doc symbol=Variant2\n+    section=Intro\n+\n doc symbol=Object\n+    section=Intro\n+\n     feature=union-feat1\n a feature\n doc symbol=Alternate\n+    section=Intro\n+\n     arg=i\n description starts on the same line\n     remainder indented the same\n@@ -151,6 +163,8 @@ doc freeform\n Another subsection\n ==================\n doc symbol=cmd\n+    section=Intro\n+\n     arg=arg1\n     description starts on a new line,\n     indented\n@@ -198,6 +212,8 @@ Note::\n     section=Since\n 2.10\n doc symbol=cmd-boxed\n+    section=Intro\n+\n     section=Plain\n If you're bored enough to read this, go see a video of boxed cats\n     feature=cmd-feat1\n@@ -211,5 +227,7 @@ another feature\n \n    <- ... has no title ...\n doc symbol=EVT_BOXED\n+    section=Intro\n+\n     feature=feat3\n a feature\ndiff --git a/tests/qapi-schema/doc-missing-colon.err b/tests/qapi-schema/doc-missing-colon.err\nindex cbcea007153..bd5862b30f3 100644\n--- a/tests/qapi-schema/doc-missing-colon.err\n+++ b/tests/qapi-schema/doc-missing-colon.err\n@@ -1 +1 @@\n-doc-missing-colon.json:4:1: line should end with ':'\n+doc-missing-colon.json:4:1: @name must end with ':'\n",
    "prefixes": [
        "07/12"
    ]
}