From nobody Mon Sep 8 09:47:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876459; cv=none; d=zohomail.com; s=zohoarc; b=hM5GWEFZSq/Uzwov4gf2xdQFn4a5QNmX7KlcnZJS4m3zM7DcFUgILuX2Nu/ZxdmR8qAmnt2jRW7X+L7ImDgKH36YramgWrM0w/XRtB2H+JcB98525fQCgfXHLeHl0q6Jkd+L8aJnX+DFAOyYfwP63m7aaMlWgE6lFx1Thc3JYWc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876459; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=6RVpBkHk7NMO1lI1YYFOF4xP7A9ERIrBpsLNs7g8GsU=; b=XXZH70Jz8hl3NxP5cZglO740gRuhN+yQYIahanT3Xzo/SJIoU3soCS6HAdQZmmOxHpSUkXYI1a4CYQMl/hnt58lJVtTbucSfdqz1cU/o7U3iWldrreJ3ak7BjoBLwTs2BIsTXPHXgmSMVWry/sdiWlo9BB7itNCDF+S8zC/aNGI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876459108128.80507699108432; Tue, 2 Sep 2025 22:14:19 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfmw-0006IV-3a; Wed, 03 Sep 2025 01:12:07 -0400 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 1utfmc-0006EI-25 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:48 -0400 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 1utfmU-0006Iq-FK for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:44 -0400 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-477--MJEYahPPRmNaVHm3MpXyA-1; Wed, 03 Sep 2025 01:11:32 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 24AD71956089; Wed, 3 Sep 2025 05:11:31 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9F61719560A2; Wed, 3 Sep 2025 05:11:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876295; 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=6RVpBkHk7NMO1lI1YYFOF4xP7A9ERIrBpsLNs7g8GsU=; b=K2Zv8V50wH3jhomMmkaAF8p5xqE/XrmXACg00TcVBMjQo5f5aBOYl6hyexz/XMuMGk3ANH Vy/BBo8vUqRz4+pYs0s7V2JLiccnAOdJLIhxK2Q3cHPP1H3GWLLSuQYGLKkmgLAp7AzXdJ Mm3O07562ojmTtKLXRuwAil6HWEG8iY= X-MC-Unique: -MJEYahPPRmNaVHm3MpXyA-1 X-Mimecast-MFC-AGG-ID: -MJEYahPPRmNaVHm3MpXyA_1756876291 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 01/18] python: backport 'Change error classes to have better repr methods' Date: Wed, 3 Sep 2025 01:11:07 -0400 Message-ID: <20250903051125.3020805-2-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876460537124100 Content-Type: text/plain; charset="utf-8" By passing all of the arguments to the base class and overriding the __str__ method when we want a different "human readable" message that isn't just printing the list of arguments, we can ensure that all custom error classes have a reasonable __repr__ implementation. In the case of ExecuteError, the pseudo-field that isn't actually correlated to an input argument can be re-imagined as a read-only property; this forces consistency in the class and makes the repr output more obviously correct. Signed-off-by: John Snow cherry picked from commit afdb7893f3b34212da4259b7202973f9a8cb85b3 --- python/qemu/qmp/error.py | 7 +++++-- python/qemu/qmp/message.py | 12 ++++++------ python/qemu/qmp/protocol.py | 7 +++++-- python/qemu/qmp/qmp_client.py | 20 +++++++++++++------- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/python/qemu/qmp/error.py b/python/qemu/qmp/error.py index 24ba4d50541..c87b078f620 100644 --- a/python/qemu/qmp/error.py +++ b/python/qemu/qmp/error.py @@ -44,7 +44,10 @@ class ProtocolError(QMPError): =20 :param error_message: Human-readable string describing the error. """ - def __init__(self, error_message: str): - super().__init__(error_message) + def __init__(self, error_message: str, *args: object): + super().__init__(error_message, *args) #: Human-readable error message, without any prefix. self.error_message: str =3D error_message + + def __str__(self) -> str: + return self.error_message diff --git a/python/qemu/qmp/message.py b/python/qemu/qmp/message.py index f76ccc90746..c2e9dd0dd54 100644 --- a/python/qemu/qmp/message.py +++ b/python/qemu/qmp/message.py @@ -178,15 +178,15 @@ class DeserializationError(ProtocolError): :param raw: The raw `bytes` that prompted the failure. """ def __init__(self, error_message: str, raw: bytes): - super().__init__(error_message) + super().__init__(error_message, raw) #: The raw `bytes` that were not understood as JSON. self.raw: bytes =3D raw =20 def __str__(self) -> str: - return "\n".join([ + return "\n".join(( super().__str__(), f" raw bytes were: {str(self.raw)}", - ]) + )) =20 =20 class UnexpectedTypeError(ProtocolError): @@ -197,13 +197,13 @@ class UnexpectedTypeError(ProtocolError): :param value: The deserialized JSON value that wasn't an object. """ def __init__(self, error_message: str, value: object): - super().__init__(error_message) + super().__init__(error_message, value) #: The JSON value that was expected to be an object. self.value: object =3D value =20 def __str__(self) -> str: strval =3D json.dumps(self.value, indent=3D2) - return "\n".join([ + return "\n".join(( super().__str__(), f" json value was: {strval}", - ]) + )) diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index a4ffdfad51b..86e588881b7 100644 --- a/python/qemu/qmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -80,7 +80,7 @@ class ConnectError(QMPError): :param exc: The root-cause exception. """ def __init__(self, error_message: str, exc: Exception): - super().__init__(error_message) + super().__init__(error_message, exc) #: Human-readable error string self.error_message: str =3D error_message #: Wrapped root cause exception @@ -108,11 +108,14 @@ class StateError(QMPError): """ def __init__(self, error_message: str, state: Runstate, required: Runstate): - super().__init__(error_message) + super().__init__(error_message, state, required) self.error_message =3D error_message self.state =3D state self.required =3D required =20 + def __str__(self) -> str: + return self.error_message + =20 F =3D TypeVar('F', bound=3DCallable[..., Any]) # pylint: disable=3Dinvali= d-name =20 diff --git a/python/qemu/qmp/qmp_client.py b/python/qemu/qmp/qmp_client.py index 2a817f9db33..a87fb565ab5 100644 --- a/python/qemu/qmp/qmp_client.py +++ b/python/qemu/qmp/qmp_client.py @@ -41,7 +41,7 @@ class _WrappedProtocolError(ProtocolError): :param exc: The root-cause exception. """ def __init__(self, error_message: str, exc: Exception): - super().__init__(error_message) + super().__init__(error_message, exc) self.exc =3D exc =20 def __str__(self) -> str: @@ -76,15 +76,21 @@ class ExecuteError(QMPError): """ def __init__(self, error_response: ErrorResponse, sent: Message, received: Message): - super().__init__(error_response.error.desc) + super().__init__(error_response, sent, received) #: The sent `Message` that caused the failure self.sent: Message =3D sent #: The received `Message` that indicated failure self.received: Message =3D received #: The parsed error response self.error: ErrorResponse =3D error_response - #: The QMP error class - self.error_class: str =3D error_response.error.class_ + + @property + def error_class(self) -> str: + """The QMP error class""" + return self.error.error.class_ + + def __str__(self) -> str: + return self.error.error.desc =20 =20 class ExecInterruptedError(QMPError): @@ -110,8 +116,8 @@ class _MsgProtocolError(ProtocolError): :param error_message: Human-readable string describing the error. :param msg: The QMP `Message` that caused the error. """ - def __init__(self, error_message: str, msg: Message): - super().__init__(error_message) + def __init__(self, error_message: str, msg: Message, *args: object): + super().__init__(error_message, msg, *args) #: The received `Message` that caused the error. self.msg: Message =3D msg =20 @@ -150,7 +156,7 @@ class BadReplyError(_MsgProtocolError): :param sent: The message that was sent that prompted the error. """ def __init__(self, error_message: str, msg: Message, sent: Message): - super().__init__(error_message, msg) + super().__init__(error_message, msg, sent) #: The sent `Message` that caused the failure self.sent =3D sent =20 --=20 2.50.1 From nobody Mon Sep 8 09:47:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876653; cv=none; d=zohomail.com; s=zohoarc; b=hSkwM+NxOTGffspQUGVHQn3lnt1xn3o99Jk2S7tEvKH0ESKWZPSf3o4lNJ1gT5gugTe01fmBdvcGNj3XvSnp7aWUL4UrpdIPMOHYXsYEB9xRRLNe+ndvEby2PU6xoPGsD/Fady/VHlQ8e8xCfN0PUVh5P+62wSqicUOFmgTu/Tk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876653; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=YHcWkc3P5BrkTo+wY0LYOsbpNSwFaqwF1CJ9Qo0H2dw=; b=TKLWrJMnPw2n82w+B4J7Ye5fULKqtFvzA7ktwdxeMLoki/85z5chPW3VgG3AtaDzj21XA5M2cyip9viscvMU5V+UfzqKJRwK6onF0OedV/MJRlGJa/BeVhWulac7hiCQb4CpPFSiaMR1LYKTWwoZI5m8Snhit5376B3hwYXW3e8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876653146372.0524237543093; Tue, 2 Sep 2025 22:17:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfoc-0007TC-0Q; Wed, 03 Sep 2025 01:13:51 -0400 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 1utfmc-0006EJ-2q for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:50 -0400 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 1utfmU-0006Iv-NZ for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:44 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-180--DUwKpPyOQ653EdDeeA8Tw-1; Wed, 03 Sep 2025 01:11:35 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 279AC180034D; Wed, 3 Sep 2025 05:11:34 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6828119560A2; Wed, 3 Sep 2025 05:11:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876296; 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=YHcWkc3P5BrkTo+wY0LYOsbpNSwFaqwF1CJ9Qo0H2dw=; b=hH6PNTKK8ajyzBLbBmk91yP//LhwoUpnroQelEve8gu5z8nf7SFraP7Lur7WZF7rE/tDwP dKEip2iWoGzsOss9rdvIab4glV1UeRZNjvhzqSeugc7Rsznav0zHGEINm/f2N+OGff9ZFF i5QZsX9y6rnr/SuffMnGPEx0itHGm6I= X-MC-Unique: -DUwKpPyOQ653EdDeeA8Tw-1 X-Mimecast-MFC-AGG-ID: -DUwKpPyOQ653EdDeeA8Tw_1756876294 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 02/18] python: backport 'EventListener: add __repr__ method' Date: Wed, 3 Sep 2025 01:11:08 -0400 Message-ID: <20250903051125.3020805-3-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876654781124100 Content-Type: text/plain; charset="utf-8" When the object is not stateful, this repr method prints what you'd expect. In cases where there are pending events, the output is augmented to illustrate that. The object itself has no idea if it's "active" or not, so it cannot convey that information. Signed-off-by: John Snow cherry picked from commit 8a6f2e136dae395fec8aa5fd77487cfe12d9e05e --- python/qemu/qmp/events.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/python/qemu/qmp/events.py b/python/qemu/qmp/events.py index 6199776cc66..66583496192 100644 --- a/python/qemu/qmp/events.py +++ b/python/qemu/qmp/events.py @@ -497,6 +497,21 @@ def __init__( #: Optional, secondary event filter. self.event_filter: Optional[EventFilter] =3D event_filter =20 + def __repr__(self) -> str: + args: List[str] =3D [] + if self.names: + args.append(f"names=3D{self.names!r}") + if self.event_filter: + args.append(f"event_filter=3D{self.event_filter!r}") + + if self._queue.qsize(): + state =3D f"" + else: + state =3D '' + + argstr =3D ", ".join(args) + return f"{type(self).__name__}{state}({argstr})" + @property def history(self) -> Tuple[Message, ...]: """ --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876375; cv=none; d=zohomail.com; s=zohoarc; b=R7Mw3nUHE6MRg2nFAdP/VwjMqdP3xkvpttSsLLRXCuCe8iF2Oyf4zWjkqylyT5752CMY/JNfyGj2xJjR8330MHvvBWB/iVu2iljX6Ln/gqoeX/HyAQO0C6aTcabTXMIXmCKTGiDZ+Bw/kMzMRdLaN/+WUiZnbv4v2VUhQz2mAQc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876375; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=oitPS37GsICvVat2dGKQ6z69gkosxIhMQsYQbDyUGIU=; b=Nqiz41UBHYQY0RKcC+klgQQ/HR3lHRdE0YMOGIP+RT3g7YzpxjoPb72qtwHxt2nQ+t9n5hllo8d8Xsd8PXYauF/Rg4/PC/Rd7hmF2QTVtK9oM5U+uooxYHrCheB6LYeJqhmAq7r/D2L71EdqOuf87KNZRdOR5Wka8ZSJEgIaQBY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876375567352.4342763610538; Tue, 2 Sep 2025 22:12:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfn2-0006Kk-BZ; Wed, 03 Sep 2025 01:12:13 -0400 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 1utfmf-0006EV-5w for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:51 -0400 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 1utfmY-0006Oz-2f for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:45 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-564-8dgmvd8DPi6tQFeZMTE81w-1; Wed, 03 Sep 2025 01:11:36 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 04EDE180034A; Wed, 3 Sep 2025 05:11:36 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 66C0E19560B1; Wed, 3 Sep 2025 05:11:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876301; 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=oitPS37GsICvVat2dGKQ6z69gkosxIhMQsYQbDyUGIU=; b=bRENlMywZGHYTJtrgWs553TEe3aEEk39aZmNQBoh08qy93qZTO9WEAW2eaJ+4c4dSWR057 TNckjEUbHJ2VG+UdBuM4GiJ9Jcj0r2sfZwKM3oC3UaSQh7j6SoUOjyu46lAjKQWZeRJUdZ 3l82AhaSd0x6CJ+9VnYB0+h8QRmOWO8= X-MC-Unique: 8dgmvd8DPi6tQFeZMTE81w-1 X-Mimecast-MFC-AGG-ID: 8dgmvd8DPi6tQFeZMTE81w_1756876296 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf , Jag Raman Subject: [PATCH v2 03/18] python: backport 'kick event queue on legacy event_pull()' Date: Wed, 3 Sep 2025 01:11:09 -0400 Message-ID: <20250903051125.3020805-4-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876376751116600 Content-Type: text/plain; charset="utf-8" This corrects an oversight in qmp-shell operation where new events will not accumulate in the event queue when pressing "enter" with an empty command buffer, so no new events show up. Reported-by: Jag Raman Signed-off-by: John Snow cherry picked from commit 0443582d16cf9efd52b2c41a7b5be7af42c856cd --- python/qemu/qmp/legacy.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/qemu/qmp/legacy.py b/python/qemu/qmp/legacy.py index 22a2b5616ef..c8d0a29b56f 100644 --- a/python/qemu/qmp/legacy.py +++ b/python/qemu/qmp/legacy.py @@ -231,6 +231,9 @@ def pull_event(self, =20 :return: The first available QMP event, or None. """ + # Kick the event loop to allow events to accumulate + self._sync(asyncio.sleep(0)) + if not wait: # wait is False/0: "do not wait, do not except." if self._qmp.events.empty(): --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876709; cv=none; d=zohomail.com; s=zohoarc; b=ee3bmnr/jTBE2ToNxxkURlzz08pN+sJP59d/4EKS8pxXkd0QluatiH7h0B1HbhB0QSFxh0s6QTFPSja3B/1THmKmjrsyWPjOqySgNPMKGcfekYap79vtdY/naAgErW/an4Yn6asMuUkMPOTlho1xGxUeuUY5Z3pwfK+pV8z2aNM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876709; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=96fcc12r2NZGoWcAWvZ/2KcZ+/kTHQQsPcjDbDUtkY8=; b=ZVYcWCDlp6IagVovjz/bWOTXTYFsIUzNsFpQikanX5V4vd5C2m0sjuEfQRnSt9str3b2o5F9gRWmQP0inFDS/e6ArLijNhzhhznlQbDlhg3k0WsMdaIndiyyRhebxJPto5ne7QgXm7mZYThTYI3eVIpZnz9ve9Jgc5QUg3lF1Vg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876709100125.87639983136808; Tue, 2 Sep 2025 22:18:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfnP-0006WO-AO; Wed, 03 Sep 2025 01:12:38 -0400 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 1utfmf-0006Ec-Fl for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:51 -0400 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 1utfmX-0006Nu-Ji for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:45 -0400 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-167-04VxaiosPrKs-pW5y5GD1Q-1; Wed, 03 Sep 2025 01:11:39 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 2678F1956050; Wed, 3 Sep 2025 05:11:38 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4AACF19560A2; Wed, 3 Sep 2025 05:11:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876300; 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=96fcc12r2NZGoWcAWvZ/2KcZ+/kTHQQsPcjDbDUtkY8=; b=jJnC99kXzAkg43tLHH/6Vy/2zi6CBUZAm7XT4QVcmS9XpWZfdpgxVVSMnw9LW6Cbe2sT6p V0FjOY/wSiNRYQ6PINZ8H1SJTrvA7Swb7QcQaQhCOmdjAEPBaK9XgoJQ8EAn0pi9vfSzxA 8nEDNyHpxPf6qQUvI32XC1rmObMxD8w= X-MC-Unique: 04VxaiosPrKs-pW5y5GD1Q-1 X-Mimecast-MFC-AGG-ID: 04VxaiosPrKs-pW5y5GD1Q_1756876298 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 04/18] python: backport 'protocol: adjust logging name when changing client name' Date: Wed, 3 Sep 2025 01:11:10 -0400 Message-ID: <20250903051125.3020805-5-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876711456124100 Content-Type: text/plain; charset="utf-8" The client name is mutable, so the logging name should also change to reflect it when it changes. Signed-off-by: John Snow cherry picked from commit e10b73c633ce138ba30bc8beccd2ab31989eaf3d --- python/qemu/qmp/protocol.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index 86e588881b7..ec4762c567b 100644 --- a/python/qemu/qmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -217,10 +217,8 @@ class AsyncProtocol(Generic[T]): # ------------------------- =20 def __init__(self, name: Optional[str] =3D None) -> None: - #: The nickname for this connection, if any. - self.name: Optional[str] =3D name - if self.name is not None: - self.logger =3D self.logger.getChild(self.name) + self._name: Optional[str] + self.name =3D name =20 # stream I/O self._reader: Optional[StreamReader] =3D None @@ -257,6 +255,24 @@ def __repr__(self) -> str: tokens.append(f"runstate=3D{self.runstate.name}") return f"<{cls_name} {' '.join(tokens)}>" =20 + @property + def name(self) -> Optional[str]: + """ + The nickname for this connection, if any. + + This name is used for differentiating instances in debug output. + """ + return self._name + + @name.setter + def name(self, name: Optional[str]) -> None: + logger =3D logging.getLogger(__name__) + if name: + self.logger =3D logger.getChild(name) + else: + self.logger =3D logger + self._name =3D name + @property # @upper_half def runstate(self) -> Runstate: """The current `Runstate` of the connection.""" --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876375; cv=none; d=zohomail.com; s=zohoarc; b=WM123yjnwrSOrsESqB4Xx1yB7QSxgQBi/IfpBQZgqWur+jOXPCkXX33TNz3jR0sVkOzuXwRHu4dVs4T8H/ZBT8WVXCBNQSd5p/4K8hbuB2Cgqp9FWKbUqW6DcBkWDA++mp3OI6EwFFpIpOw3kjUfgRS/bi8gR56F5vWRqPXo5UM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876375; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=22hO3JJMxrFCOXkNxcoFNtgJT5F0JBkIh0Au/Df0Gzw=; b=W3Rd9NDxmF5WnwO0IdKV+48CFJH6J52odoOQWX+CvX8cO8Ia5lGEi8ZjdFgh/Pe0BR/a8g4OuJMx/Pm6/SxCgerZSE6w11DTU02XyfK/7LpFaXAlZM39BaQqiAnXPwadkYikHKsZq26LOm58C22T/aiI8KOZPTOuhL6mXdHmFVc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175687637532572.94231190548874; Tue, 2 Sep 2025 22:12:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfn9-0006Mh-Dc; Wed, 03 Sep 2025 01:12:19 -0400 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 1utfmf-0006Em-Uz for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:52 -0400 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 1utfmZ-0006RK-Vx for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:47 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-384-_4NXX3MRNnyC8KughJojBw-1; Wed, 03 Sep 2025 01:11:40 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E62351800447; Wed, 3 Sep 2025 05:11:39 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6EC0119560A2; Wed, 3 Sep 2025 05:11:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876302; 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=22hO3JJMxrFCOXkNxcoFNtgJT5F0JBkIh0Au/Df0Gzw=; b=Xzs9utczT60W4wMHkmlmugw6Wvsn6Z7aQJSlRMHPpVSpNgZqQqc09TCkmEgooIAtWarsH8 TgLY3oZPbY97JuG3YhiZcLbpT/+UUCqcabak/HFmfvEKV1BS8wzWIgPj5fQFZlmabPe032 7G0CasyBc9beCagAn1SsndEH0/aUaKU= X-MC-Unique: _4NXX3MRNnyC8KughJojBw-1 X-Mimecast-MFC-AGG-ID: _4NXX3MRNnyC8KughJojBw_1756876300 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 05/18] python: backport 'drop Python3.6 workarounds' Date: Wed, 3 Sep 2025 01:11:11 -0400 Message-ID: <20250903051125.3020805-6-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876379762124101 Content-Type: text/plain; charset="utf-8" Now that the minimum version is 3.7, drop some of the 3.6-specific hacks we've been carrying. A single remaining compatibility hack concerning 3.6's lack of @asynccontextmanager is addressed in the following commit. Signed-off-by: John Snow cherry picked from commit 3e8e34e594cfc6b707e6f67959166acde4b421b8 --- python/qemu/qmp/protocol.py | 48 +++++++--------- python/qemu/qmp/qmp_tui.py | 8 +-- python/qemu/qmp/util.py | 107 ++---------------------------------- python/tests/protocol.py | 8 +-- 4 files changed, 33 insertions(+), 138 deletions(-) diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index ec4762c567b..958aeca08ac 100644 --- a/python/qemu/qmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -15,6 +15,7 @@ =20 import asyncio from asyncio import StreamReader, StreamWriter +from contextlib import asynccontextmanager from enum import Enum from functools import wraps import logging @@ -22,6 +23,7 @@ from ssl import SSLContext from typing import ( Any, + AsyncGenerator, Awaitable, Callable, Generic, @@ -36,13 +38,10 @@ from .error import QMPError from .util import ( bottom_half, - create_task, exception_summary, flush, - is_closing, pretty_traceback, upper_half, - wait_closed, ) =20 =20 @@ -340,9 +339,8 @@ async def start_server(self, address: SocketAddrT, This exception will wrap a more concrete one. In most cases, the wrapped exception will be `OSError`. """ - await self._session_guard( - self._do_start_server(address, ssl), - 'Failed to establish connection') + async with self._session_guard('Failed to establish connection'): + await self._do_start_server(address, ssl) assert self.runstate =3D=3D Runstate.CONNECTING =20 @upper_half @@ -365,12 +363,10 @@ async def accept(self) -> None: """ if self._accepted is None: raise QMPError("Cannot call accept() before start_server().") - await self._session_guard( - self._do_accept(), - 'Failed to establish connection') - await self._session_guard( - self._establish_session(), - 'Failed to establish session') + async with self._session_guard('Failed to establish connection'): + await self._do_accept() + async with self._session_guard('Failed to establish session'): + await self._establish_session() assert self.runstate =3D=3D Runstate.RUNNING =20 @upper_half @@ -395,12 +391,10 @@ async def connect(self, address: Union[SocketAddrT, s= ocket.socket], protocol-level failure occurs while establishing a new session, the wrapped error may also be an `QMPError`. """ - await self._session_guard( - self._do_connect(address, ssl), - 'Failed to establish connection') - await self._session_guard( - self._establish_session(), - 'Failed to establish session') + async with self._session_guard('Failed to establish connection'): + await self._do_connect(address, ssl) + async with self._session_guard('Failed to establish session'): + await self._establish_session() assert self.runstate =3D=3D Runstate.RUNNING =20 @upper_half @@ -421,7 +415,8 @@ async def disconnect(self) -> None: # Section: Session machinery # -------------------------- =20 - async def _session_guard(self, coro: Awaitable[None], emsg: str) -> No= ne: + @asynccontextmanager + async def _session_guard(self, emsg: str) -> AsyncGenerator[None, None= ]: """ Async guard function used to roll back to `IDLE` on any error. =20 @@ -438,10 +433,9 @@ async def _session_guard(self, coro: Awaitable[None], = emsg: str) -> None: :raise ConnectError: When any other error is encountered in the guarded block. """ - # Note: After Python 3.6 support is removed, this should be an - # @asynccontextmanager instead of accepting a callback. try: - await coro + # Caller's code runs here. + yield except BaseException as err: self.logger.error("%s: %s", emsg, exception_summary(err)) self.logger.debug("%s:\n%s\n", emsg, pretty_traceback()) @@ -682,8 +676,8 @@ async def _establish_session(self) -> None: reader_coro =3D self._bh_loop_forever(self._bh_recv_message, 'Read= er') writer_coro =3D self._bh_loop_forever(self._bh_send_message, 'Writ= er') =20 - self._reader_task =3D create_task(reader_coro) - self._writer_task =3D create_task(writer_coro) + self._reader_task =3D asyncio.create_task(reader_coro) + self._writer_task =3D asyncio.create_task(writer_coro) =20 self._bh_tasks =3D asyncio.gather( self._reader_task, @@ -708,7 +702,7 @@ def _schedule_disconnect(self) -> None: if not self._dc_task: self._set_state(Runstate.DISCONNECTING) self.logger.debug("Scheduling disconnect.") - self._dc_task =3D create_task(self._bh_disconnect()) + self._dc_task =3D asyncio.create_task(self._bh_disconnect()) =20 @upper_half async def _wait_disconnect(self) -> None: @@ -844,13 +838,13 @@ async def _bh_close_stream(self, error_pathway: bool = =3D False) -> None: if not self._writer: return =20 - if not is_closing(self._writer): + if not self._writer.is_closing(): self.logger.debug("Closing StreamWriter.") self._writer.close() =20 self.logger.debug("Waiting for StreamWriter to close ...") try: - await wait_closed(self._writer) + await self._writer.wait_closed() except Exception: # pylint: disable=3Dbroad-except # It's hard to tell if the Stream is already closed or # not. Even if one of the tasks has failed, it may have diff --git a/python/qemu/qmp/qmp_tui.py b/python/qemu/qmp/qmp_tui.py index 2d9ebbd20bc..562be008d5e 100644 --- a/python/qemu/qmp/qmp_tui.py +++ b/python/qemu/qmp/qmp_tui.py @@ -40,7 +40,7 @@ from .message import DeserializationError, Message, UnexpectedTypeError from .protocol import ConnectError, Runstate from .qmp_client import ExecInterruptedError, QMPClient -from .util import create_task, pretty_traceback +from .util import pretty_traceback =20 =20 # The name of the signal that is used to update the history list @@ -225,7 +225,7 @@ def cb_send_to_server(self, raw_msg: str) -> None: """ try: msg =3D Message(bytes(raw_msg, encoding=3D'utf-8')) - create_task(self._send_to_server(msg)) + asyncio.create_task(self._send_to_server(msg)) except (DeserializationError, UnexpectedTypeError) as err: raw_msg =3D format_json(raw_msg) logging.info('Invalid message: %s', err.error_message) @@ -246,7 +246,7 @@ def kill_app(self) -> None: Initiates killing of app. A bridge between asynchronous and synchr= onous code. """ - create_task(self._kill_app()) + asyncio.create_task(self._kill_app()) =20 async def _kill_app(self) -> None: """ @@ -393,7 +393,7 @@ def run(self, debug: bool =3D False) -> None: handle_mouse=3DTrue, event_loop=3Devent_loop) =20 - create_task(self.manage_connection(), self.aloop) + self.aloop.create_task(self.manage_connection()) try: main_loop.run() except Exception as err: diff --git a/python/qemu/qmp/util.py b/python/qemu/qmp/util.py index ca6225e9cda..0b3e781373d 100644 --- a/python/qemu/qmp/util.py +++ b/python/qemu/qmp/util.py @@ -1,25 +1,15 @@ """ Miscellaneous Utilities =20 -This module provides asyncio utilities and compatibility wrappers for -Python 3.6 to provide some features that otherwise become available in -Python 3.7+. - -Various logging and debugging utilities are also provided, such as -`exception_summary()` and `pretty_traceback()`, used primarily for -adding information into the logging stream. +This module provides asyncio and various logging and debugging +utilities, such as `exception_summary()` and `pretty_traceback()`, used +primarily for adding information into the logging stream. """ =20 import asyncio import sys import traceback -from typing import ( - Any, - Coroutine, - Optional, - TypeVar, - cast, -) +from typing import TypeVar, cast =20 =20 T =3D TypeVar('T') @@ -79,95 +69,6 @@ def bottom_half(func: T) -> T: return func =20 =20 -# ------------------------------- -# Section: Compatibility Wrappers -# ------------------------------- - - -def create_task(coro: Coroutine[Any, Any, T], - loop: Optional[asyncio.AbstractEventLoop] =3D None - ) -> 'asyncio.Future[T]': - """ - Python 3.6-compatible `asyncio.create_task` wrapper. - - :param coro: The coroutine to execute in a task. - :param loop: Optionally, the loop to create the task in. - - :return: An `asyncio.Future` object. - """ - if sys.version_info >=3D (3, 7): - if loop is not None: - return loop.create_task(coro) - return asyncio.create_task(coro) # pylint: disable=3Dno-member - - # Python 3.6: - return asyncio.ensure_future(coro, loop=3Dloop) - - -def is_closing(writer: asyncio.StreamWriter) -> bool: - """ - Python 3.6-compatible `asyncio.StreamWriter.is_closing` wrapper. - - :param writer: The `asyncio.StreamWriter` object. - :return: `True` if the writer is closing, or closed. - """ - if sys.version_info >=3D (3, 7): - return writer.is_closing() - - # Python 3.6: - transport =3D writer.transport - assert isinstance(transport, asyncio.WriteTransport) - return transport.is_closing() - - -async def wait_closed(writer: asyncio.StreamWriter) -> None: - """ - Python 3.6-compatible `asyncio.StreamWriter.wait_closed` wrapper. - - :param writer: The `asyncio.StreamWriter` to wait on. - """ - if sys.version_info >=3D (3, 7): - await writer.wait_closed() - return - - # Python 3.6 - transport =3D writer.transport - assert isinstance(transport, asyncio.WriteTransport) - - while not transport.is_closing(): - await asyncio.sleep(0) - - # This is an ugly workaround, but it's the best I can come up with. - sock =3D transport.get_extra_info('socket') - - if sock is None: - # Our transport doesn't have a socket? ... - # Nothing we can reasonably do. - return - - while sock.fileno() !=3D -1: - await asyncio.sleep(0) - - -def asyncio_run(coro: Coroutine[Any, Any, T], *, debug: bool =3D False) ->= T: - """ - Python 3.6-compatible `asyncio.run` wrapper. - - :param coro: A coroutine to execute now. - :return: The return value from the coroutine. - """ - if sys.version_info >=3D (3, 7): - return asyncio.run(coro, debug=3Ddebug) - - # Python 3.6 - loop =3D asyncio.get_event_loop() - loop.set_debug(debug) - ret =3D loop.run_until_complete(coro) - loop.close() - - return ret - - # ---------------------------- # Section: Logging & Debugging # ---------------------------- diff --git a/python/tests/protocol.py b/python/tests/protocol.py index 56c4d441f9c..c254c77b176 100644 --- a/python/tests/protocol.py +++ b/python/tests/protocol.py @@ -8,7 +8,6 @@ =20 from qemu.qmp import ConnectError, Runstate from qemu.qmp.protocol import AsyncProtocol, StateError -from qemu.qmp.util import asyncio_run, create_task =20 =20 class NullProtocol(AsyncProtocol[None]): @@ -124,7 +123,7 @@ async def _runner(): if allow_cancellation: return raise - return create_task(_runner()) + return asyncio.create_task(_runner()) =20 =20 @contextmanager @@ -271,7 +270,7 @@ async def _watcher(): msg=3Df"Expected state '{state.name}'", ) =20 - self.runstate_watcher =3D create_task(_watcher()) + self.runstate_watcher =3D asyncio.create_task(_watcher()) # Kick the loop and force the task to block on the event. await asyncio.sleep(0) =20 @@ -589,7 +588,8 @@ async def _asyncTearDown(self): async def testSmoke(self): with TemporaryDirectory(suffix=3D'.qmp') as tmpdir: sock =3D os.path.join(tmpdir, type(self.proto).__name__ + ".so= ck") - server_task =3D create_task(self.server.start_server_and_accep= t(sock)) + server_task =3D asyncio.create_task( + self.server.start_server_and_accept(sock)) =20 # give the server a chance to start listening [...] await asyncio.sleep(0) --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876450; cv=none; d=zohomail.com; s=zohoarc; b=Thy7L+rTWwC9BosftFeTE0BstZeIAQA0pTsiEtARoC4kaB6v4nRtXcvHcztGnpLP80cBIrGvOx/RvUoGDqgA/pWQGY+mojBAtA8RFKVH69GuMeZuBwTLyL2114hUPU2wgZP2n0QCf61eZwbfSIicl9EXIEVvmVb9YigqSiCIZLk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876450; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vvlcoNBRtTemniW9XA73ofAIfmI7j9QtIOho6OWMmb8=; b=Tn12bGd+NHGkBlkkOLXgo91J8nZMmUABM9R/94iuk3DIMOHtfF8i2gRWuVbDNdYPk1Y5Ja/q/HjgrOGEJho9TEA1DS8RXFQl5HqlGzEGAoYig/Dqrdgvl8hxiiSGIPa7OJOoTZ3QPhEVkb9mzGcVUWFffyacym6O1OsCRKKisFs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876450791439.7520760267262; Tue, 2 Sep 2025 22:14:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfoC-0007Bd-Oy; Wed, 03 Sep 2025 01:13:25 -0400 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 1utfmi-0006F2-Sy for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:56 -0400 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 1utfme-0006SA-Va for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:51 -0400 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-257-wBxDjXCUPb6nASM_EKdKSg-1; Wed, 03 Sep 2025 01:11:42 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 B84BF195608C; Wed, 3 Sep 2025 05:11:41 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3E6FC19560A2; Wed, 3 Sep 2025 05:11:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876306; 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=vvlcoNBRtTemniW9XA73ofAIfmI7j9QtIOho6OWMmb8=; b=UI7r4JTEZ0FR0q8WbFU0+UBAuzoCk8ENE1AdGffKESxf6XKrFm5qurlYbk/2pO5pA0TNue NyIq755m++md1/WND9VhAFK3aJuOkejaX/BDFpr6fygBsJ3vTjvmMWPY9o9LSUxCAblVFS orrmrOIQuXOHUs9rDifL4u/pmY0tw/A= X-MC-Unique: wBxDjXCUPb6nASM_EKdKSg-1 X-Mimecast-MFC-AGG-ID: wBxDjXCUPb6nASM_EKdKSg_1756876301 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 06/18] python: backport 'qmp-shell: add common_parser()' Date: Wed, 3 Sep 2025 01:11:12 -0400 Message-ID: <20250903051125.3020805-7-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876452517124100 Content-Type: text/plain; charset="utf-8" Signed-off-by: John Snow cherry picked from commit 20a88c2471f37d10520b2409046d59e1d0f1e905 Signed-off-by: John Snow --- python/qemu/qmp/qmp_shell.py | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/python/qemu/qmp/qmp_shell.py b/python/qemu/qmp/qmp_shell.py index 98e684e9e8a..02028e94b5a 100644 --- a/python/qemu/qmp/qmp_shell.py +++ b/python/qemu/qmp/qmp_shell.py @@ -514,21 +514,27 @@ def die(msg: str) -> NoReturn: sys.exit(1) =20 =20 +def common_parser() -> argparse.ArgumentParser: + """Build common parsing options used by qmp-shell and qmp-shell-wrap."= "" + parser =3D argparse.ArgumentParser() + parser.add_argument('-H', '--hmp', action=3D'store_true', + help=3D'Use HMP interface') + parser.add_argument('-v', '--verbose', action=3D'store_true', + help=3D'Verbose (echo commands sent and received)') + parser.add_argument('-p', '--pretty', action=3D'store_true', + help=3D'Pretty-print JSON') + parser.add_argument('-l', '--logfile', + help=3D'Save log of all QMP messages to PATH') + return parser + + def main() -> None: """ qmp-shell entry point: parse command line arguments and start the REPL. """ - parser =3D argparse.ArgumentParser() - parser.add_argument('-H', '--hmp', action=3D'store_true', - help=3D'Use HMP interface') + parser =3D common_parser() parser.add_argument('-N', '--skip-negotiation', action=3D'store_true', help=3D'Skip negotiate (for qemu-ga)') - parser.add_argument('-v', '--verbose', action=3D'store_true', - help=3D'Verbose (echo commands sent and received)') - parser.add_argument('-p', '--pretty', action=3D'store_true', - help=3D'Pretty-print JSON') - parser.add_argument('-l', '--logfile', - help=3D'Save log of all QMP messages to PATH') =20 default_server =3D os.environ.get('QMP_SOCKET') parser.add_argument('qmp_server', action=3D'store', @@ -564,16 +570,7 @@ def main_wrap() -> None: qmp-shell-wrap entry point: parse command line arguments and start the REPL. """ - parser =3D argparse.ArgumentParser() - parser.add_argument('-H', '--hmp', action=3D'store_true', - help=3D'Use HMP interface') - parser.add_argument('-v', '--verbose', action=3D'store_true', - help=3D'Verbose (echo commands sent and received)') - parser.add_argument('-p', '--pretty', action=3D'store_true', - help=3D'Pretty-print JSON') - parser.add_argument('-l', '--logfile', - help=3D'Save log of all QMP messages to PATH') - + parser =3D common_parser() parser.add_argument('command', nargs=3Dargparse.REMAINDER, help=3D'QEMU command line to invoke') =20 --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876376; cv=none; d=zohomail.com; s=zohoarc; b=dD8zF9bQTIu8if9jJVjyXGn7oNkBylmvLsUS7pT/Q9yQVgWBH3xto0mbnTRhvXJE9/01D44R2qt/W1B2+GrJ5umuT/qD/19jEOV9f1OA3NyaXIxC2H+gKbhwOnGurl4pH83CRQLUWjJPb6qsUE3xLjXCoAqij7kRyoAWQ3Ydvwo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876376; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=M6gKCmGtM4v/7K8Q4fJ0OL1dh2KHpJ2JMgXdjAgZP6A=; b=KZu2Sw+sMuvGGACKX/7BgX+JjG+tRAXh2nM3oY9G2Xn85IUidLxtdNF1e0b6fIh68tHpxPWzEq4Petsyk6BESdLgRPdbRVE/E96/WmCP/d79xDCENOOqO9NobdGnmne3o5tHVCSyDMa4kxe4zD3dc073P+jjioMe1KUXrv36cr4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876376136919.656535495387; Tue, 2 Sep 2025 22:12:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfn9-0006Mj-Cp; Wed, 03 Sep 2025 01:12:19 -0400 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 1utfmi-0006F4-Sx for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:56 -0400 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 1utfmg-0006Sm-Bj for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:52 -0400 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-219-4l8Up2UgNdq7gvCTHaWssg-1; Wed, 03 Sep 2025 01:11:46 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 9200919560B4; Wed, 3 Sep 2025 05:11:45 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 275EF19560B1; Wed, 3 Sep 2025 05:11:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876308; 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=M6gKCmGtM4v/7K8Q4fJ0OL1dh2KHpJ2JMgXdjAgZP6A=; b=eKWmAJRsb5qYNieoudutsu1xmPh6ot6pdOVH2wHNRwViRv8TQI6/dZGhWYjNKf/jJ6f6hf pkoNNKWGQGzhLzTfQalOAE6gyZLrkHZiv+ZAKdCIborkLhGyQDqGk7Bb6lJqL6QF8kNALC ngSHtJ8Rj6PqQJWDkicxcj1TK6TXcgE= X-MC-Unique: 4l8Up2UgNdq7gvCTHaWssg-1 X-Mimecast-MFC-AGG-ID: 4l8Up2UgNdq7gvCTHaWssg_1756876306 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf , Adam Dorsey , Adam Dorsey Subject: [PATCH v2 07/18] python: backport 'feat: allow setting read buffer limit' Date: Wed, 3 Sep 2025 01:11:13 -0400 Message-ID: <20250903051125.3020805-8-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876379945124100 Content-Type: text/plain; charset="utf-8" From: Adam Dorsey Expose the limit parameter of the underlying StreamReader and StreamWriter instances. This is helpful for the use case of transferring files in and out of a VM via the QEMU guest agent's guest-file-open, guest-file-read, guest-file-wri= te, and guest-file-close methods, as it allows pushing the buffer size up to the guest agent's limit of 48MB per transfer. Signed-off-by: Adam Dorsey cherry picked from commit 9ba6a698344eb3b570fa4864e906c54042824cd6 cherry picked from commit e4d0d3f835d82283ee0e48438d1b154e18303491 [Squashed in linter fixups. --js] Signed-off-by: John Snow --- python/qemu/qmp/protocol.py | 25 ++++++++++++++++--------- python/qemu/qmp/qmp_client.py | 18 ++++++++++++++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index 958aeca08ac..3d5eb553aad 100644 --- a/python/qemu/qmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -53,6 +53,9 @@ UnixAddrT =3D str SocketAddrT =3D Union[UnixAddrT, InternetAddrT] =20 +# Maximum allowable size of read buffer, default +_DEFAULT_READBUFLEN =3D 64 * 1024 + =20 class Runstate(Enum): """Protocol session runstate.""" @@ -202,22 +205,26 @@ class AsyncProtocol(Generic[T]): will log to 'qemu.qmp.protocol', but each individual connection can be given its own logger by giving it a name; messages will then log to 'qemu.qmp.protocol.${name}'. + :param readbuflen: + The maximum read buffer length of the underlying StreamReader + instance. """ # pylint: disable=3Dtoo-many-instance-attributes =20 #: Logger object for debugging messages from this connection. logger =3D logging.getLogger(__name__) =20 - # Maximum allowable size of read buffer - _limit =3D 64 * 1024 - # ------------------------- # Section: Public interface # ------------------------- =20 - def __init__(self, name: Optional[str] =3D None) -> None: + def __init__( + self, name: Optional[str] =3D None, + readbuflen: int =3D _DEFAULT_READBUFLEN + ) -> None: self._name: Optional[str] self.name =3D name + self.readbuflen =3D readbuflen =20 # stream I/O self._reader: Optional[StreamReader] =3D None @@ -574,7 +581,7 @@ async def _do_start_server(self, address: SocketAddrT, port=3Daddress[1], ssl=3Dssl, backlog=3D1, - limit=3Dself._limit, + limit=3Dself.readbuflen, ) else: coro =3D asyncio.start_unix_server( @@ -582,7 +589,7 @@ async def _do_start_server(self, address: SocketAddrT, path=3Daddress, ssl=3Dssl, backlog=3D1, - limit=3Dself._limit, + limit=3Dself.readbuflen, ) =20 # Allow runstate watchers to witness 'CONNECTING' state; some @@ -637,7 +644,7 @@ async def _do_connect(self, address: Union[SocketAddrT,= socket.socket], "fd=3D%d, family=3D%r, type=3D%r", address.fileno(), address.family, address.ty= pe) connect =3D asyncio.open_connection( - limit=3Dself._limit, + limit=3Dself.readbuflen, ssl=3Dssl, sock=3Daddress, ) @@ -647,14 +654,14 @@ async def _do_connect(self, address: Union[SocketAddr= T, socket.socket], address[0], address[1], ssl=3Dssl, - limit=3Dself._limit, + limit=3Dself.readbuflen, ) else: self.logger.debug("Connecting to file://%s ...", address) connect =3D asyncio.open_unix_connection( path=3Daddress, ssl=3Dssl, - limit=3Dself._limit, + limit=3Dself.readbuflen, ) =20 self._reader, self._writer =3D await connect diff --git a/python/qemu/qmp/qmp_client.py b/python/qemu/qmp/qmp_client.py index a87fb565ab5..d826331b6d5 100644 --- a/python/qemu/qmp/qmp_client.py +++ b/python/qemu/qmp/qmp_client.py @@ -170,6 +170,12 @@ class QMPClient(AsyncProtocol[Message], Events): =20 :param name: Optional nickname for the connection, used for logging. =20 + :param readbuflen: + The maximum buffer length for reads and writes to and from the QMP + server, in bytes. Default is 10MB. If `QMPClient` is used to + connect to a guest agent to transfer files via ``guest-file-read``/ + ``guest-file-write``, increasing this value may be required. + Basic script-style usage looks like this:: =20 qmp =3D QMPClient('my_virtual_machine_name') @@ -203,14 +209,18 @@ async def run(self, address=3D'/tmp/qemu.socket'): #: Logger object used for debugging messages. logger =3D logging.getLogger(__name__) =20 - # Read buffer limit; 10MB like libvirt default - _limit =3D 10 * 1024 * 1024 + # Read buffer default limit; 10MB like libvirt default + _readbuflen =3D 10 * 1024 * 1024 =20 # Type alias for pending execute() result items _PendingT =3D Union[Message, ExecInterruptedError] =20 - def __init__(self, name: Optional[str] =3D None) -> None: - super().__init__(name) + def __init__( + self, + name: Optional[str] =3D None, + readbuflen: int =3D _readbuflen + ) -> None: + super().__init__(name, readbuflen) Events.__init__(self) =20 #: Whether or not to await a greeting after establishing a connect= ion. --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876642; cv=none; d=zohomail.com; s=zohoarc; b=GcEU2rJ3a8bRvrWw0rorHq/6iTeYCUv0nBJzdLL7NmyEjbDkPdJ0hgfmbah3/DEaJWrg7UtX83MSLymgYXKcM8migmADFI0wGVz6yQsO2fu3lHWuan7eoKQJo109wmDrKFcd/0S3WdtBbvJTe0M73Ros5KkELPVYDE6bdhs5jUY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876642; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4Ij7nY8K9/pQd7GIXPh8H0NEp1+Fx24DKp7yG2jE9/s=; b=eVJ8jsMqS7vsMaHgyW1JM/9jGuzwovYFmAoGZKxbef6Wtnjc+QqS7kJTOz6sZ+d+pXRoALuK4Bou0+W1a/FRsx2xTxedooF+7dm75PTtORb66l6cZvF9GjvTYH8iStCAE57vW+6mUYbzaBNdedKqn3kLpIydH6c49rdrDtFOGQs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876641988138.26121780184906; Tue, 2 Sep 2025 22:17:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfnh-0006io-6G; Wed, 03 Sep 2025 01:12:54 -0400 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 1utfml-0006FP-V5 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:01 -0400 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 1utfmk-0006Tn-4J for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:55 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-522-YrcW1mHNNEOKpj5b7nOL0Q-1; Wed, 03 Sep 2025 01:11:49 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EF1C51800350; Wed, 3 Sep 2025 05:11:48 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0885F19560A2; Wed, 3 Sep 2025 05:11:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876313; 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=4Ij7nY8K9/pQd7GIXPh8H0NEp1+Fx24DKp7yG2jE9/s=; b=KcUSO5E/A5+DFJX8BgVd62G0oVX3aDXmM2AJgsN3hQ3xjujyo/AiuDWRHfddwLf3qKbWtC 5hniwH8oManltCfGJsiTj+KrBQjgq39+pjI/Oc2sNOFlb7mvv54KItRnp8RgGfGqZaSyKW JD49PxImk36hTcfkxm2vhf+3yyjlxJQ= X-MC-Unique: YrcW1mHNNEOKpj5b7nOL0Q-1 X-Mimecast-MFC-AGG-ID: YrcW1mHNNEOKpj5b7nOL0Q_1756876309 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 08/18] python: backport 'make require() preserve async-ness' Date: Wed, 3 Sep 2025 01:11:14 -0400 Message-ID: <20250903051125.3020805-9-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876644447116600 Content-Type: text/plain; charset="utf-8" This is not strictly needed functionality-wise, but doing this allows sphinx to see which decorated methods are async. Without this, sphinx misses the "async" classifier on generated docs, which ... for an async library, isn't great. It does make an already gnarly function even gnarlier, though. So, what's going on here? A synchronous function (like require() before this patch) can return a coroutine that can be awaited on, for example: def some_func(): return asyncio.task(asyncio.sleep(5)) async def some_async_func(): await some_func() However, this function is not considered to be an "async" function in the eyes of the abstract syntax tree. Specifically, some_func.__code__.co_flags will not be set with CO_COROUTINE. The interpreter uses this flag to know if it's legal to use "await" from within the body of the function. Since this function is just wrapping another function, it doesn't matter much for the decorator, but sphinx uses the stdlib inspect.iscoroutinefunction() to determine when to add the "async" prefix in generated output. This function uses the presence of CO_COROUTINE. So, in order to preserve the "async" flag for docs, the require() decorator needs to differentiate based on whether it is decorating a sync or async function and use a different wrapping mechanism accordingly. Phew. Signed-off-by: John Snow cherry picked from commit 40aa9699d619849f528032aa456dd061a4afa957 Signed-off-by: John Snow --- python/qemu/qmp/protocol.py | 53 ++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index 3d5eb553aad..4d8a39f014b 100644 --- a/python/qemu/qmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -18,6 +18,7 @@ from contextlib import asynccontextmanager from enum import Enum from functools import wraps +from inspect import iscoroutinefunction import logging import socket from ssl import SSLContext @@ -130,6 +131,25 @@ def require(required_state: Runstate) -> Callable[[F],= F]: :param required_state: The `Runstate` required to invoke this method. :raise StateError: When the required `Runstate` is not met. """ + def _check(proto: 'AsyncProtocol[Any]') -> None: + name =3D type(proto).__name__ + if proto.runstate =3D=3D required_state: + return + + if proto.runstate =3D=3D Runstate.CONNECTING: + emsg =3D f"{name} is currently connecting." + elif proto.runstate =3D=3D Runstate.DISCONNECTING: + emsg =3D (f"{name} is disconnecting." + " Call disconnect() to return to IDLE state.") + elif proto.runstate =3D=3D Runstate.RUNNING: + emsg =3D f"{name} is already connected and running." + elif proto.runstate =3D=3D Runstate.IDLE: + emsg =3D f"{name} is disconnected and idle." + else: + assert False + + raise StateError(emsg, proto.runstate, required_state) + def _decorator(func: F) -> F: # _decorator is the decorator that is built by calling the # require() decorator factory; e.g.: @@ -140,29 +160,20 @@ def _decorator(func: F) -> F: @wraps(func) def _wrapper(proto: 'AsyncProtocol[Any]', *args: Any, **kwargs: Any) -> Any: - # _wrapper is the function that gets executed prior to the - # decorated method. - - name =3D type(proto).__name__ - - if proto.runstate !=3D required_state: - if proto.runstate =3D=3D Runstate.CONNECTING: - emsg =3D f"{name} is currently connecting." - elif proto.runstate =3D=3D Runstate.DISCONNECTING: - emsg =3D (f"{name} is disconnecting." - " Call disconnect() to return to IDLE state.") - elif proto.runstate =3D=3D Runstate.RUNNING: - emsg =3D f"{name} is already connected and running." - elif proto.runstate =3D=3D Runstate.IDLE: - emsg =3D f"{name} is disconnected and idle." - else: - assert False - raise StateError(emsg, proto.runstate, required_state) - # No StateError, so call the wrapped method. + _check(proto) return func(proto, *args, **kwargs) =20 - # Return the decorated method; - # Transforming Func to Decorated[Func]. + @wraps(func) + async def _async_wrapper(proto: 'AsyncProtocol[Any]', + *args: Any, **kwargs: Any) -> Any: + _check(proto) + return await func(proto, *args, **kwargs) + + # Return the decorated method; F =3D> Decorated[F] + # Use an async version when applicable, which + # preserves async signature generation in sphinx. + if iscoroutinefunction(func): + return cast(F, _async_wrapper) return cast(F, _wrapper) =20 # Return the decorator instance from the decorator factory. Phew! --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876708; cv=none; d=zohomail.com; s=zohoarc; b=UNXtZdo/WVHrA/iADw825wIm2mgAsoNFYbN6iJ7qrqo3xE4vPJZiUePAQuAlzlK1htB0cZH7++0L86y5AjUwOiigRtfXK0D84kPLERwWL8hZBt8VbLMBrx0BEgI9LAMO5H0iUmfLcC7U6272trZsB2wvFNocFURaFbzIRiEtrkM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876708; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tagIbdrrDMrYKknepF7MVfnL4rHnC0ypp6LupSkyNl8=; b=Vy/lDPSS3GjY2sAb9S0hgyptQdLci51/ZlnAwOmeVuytuvwpysCx7lURQD/hsm/hpHXa1771kHmOhi3Qk7Z5N6NPqMo6606g1ohwFA+hexmsZpt84UnN8UvplUFiyUeISbts/YoqR+scbeUogSMHeVM+XDanqB4RpVF2OgdjZ1c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876708834119.36320572238162; Tue, 2 Sep 2025 22:18:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfpP-0000Le-Ev; Wed, 03 Sep 2025 01:14:39 -0400 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 1utfmm-0006Fi-V6 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:01 -0400 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 1utfmk-0006Ts-Hr for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:11:56 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-584-5dRiywpsPzmidlaGIJhjKQ-1; Wed, 03 Sep 2025 01:11:52 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1EFA1180034F; Wed, 3 Sep 2025 05:11:51 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4058F19560A2; Wed, 3 Sep 2025 05:11:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876313; 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=tagIbdrrDMrYKknepF7MVfnL4rHnC0ypp6LupSkyNl8=; b=ePTqNglwl848Vygt9EVyGUoPeHL+OEJlIja7v71p5iFgPjTBaPvE3RZL4sC/b17iWfuUlU 0ZZuLPT5vkRzQWfYPCyxhkxcSWqp667oRDjFHMSAKpPI+ng82ajwWS7CUT/F00itJqw7HH rHDi0w8GjTloL9dqUjAHdglxAjEQSdY= X-MC-Unique: 5dRiywpsPzmidlaGIJhjKQ-1 X-Mimecast-MFC-AGG-ID: 5dRiywpsPzmidlaGIJhjKQ_1756876311 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 09/18] python: backport 'qmp-shell-wrap: handle missing binary gracefully' Date: Wed, 3 Sep 2025 01:11:15 -0400 Message-ID: <20250903051125.3020805-10-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876710829116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: John Snow cherry picked from commit 9c889dcbd58817b0c917a9d2dd16161f48ac8203 Signed-off-by: John Snow --- python/qemu/qmp/qmp_shell.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/qemu/qmp/qmp_shell.py b/python/qemu/qmp/qmp_shell.py index 02028e94b5a..c923ff09e1f 100644 --- a/python/qemu/qmp/qmp_shell.py +++ b/python/qemu/qmp/qmp_shell.py @@ -607,6 +607,8 @@ def main_wrap() -> None: =20 for _ in qemu.repl(): pass + except FileNotFoundError: + sys.stderr.write(f"ERROR: QEMU executable '{cmd[0]}' not found.\n") finally: os.unlink(sockpath) =20 --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876399; cv=none; d=zohomail.com; s=zohoarc; b=MXpDaRlUqn0s+PmIXimzqx8NPY/PIyKBQmalrpYKdS8elRC1nT8J6B1GDQWFXqAKaZinuUO6JANILqqWPZei/lgeTIyRuA0eGgwTSknX8TkMHDZay8G/kP5tp3iOUgiCdJ4swWtejyql8U6hLTIq9MMIVGsDl812l9Cm4CA9ZoY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876399; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=mW0ivbCeARcW77uG+hGeVTu54bG1KQkuvpiyp/K2kcE=; b=fzqVlp/CTdFQPx10tELDYKfC0s3pM8SNgiEYj1am4qjFHhc1dkdTojF2lYNqtgZf1rB2pFYIdtzRHdtFrnHHddRj0y0and7qyIwdus9cg29I4ZnYDlcUkT+UrnUsvXvpK+NpEUZlsMNsQV6/S6V3ftykaq0F5mahP2slzbPUfCI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876399344316.6836894689801; Tue, 2 Sep 2025 22:13:19 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfnw-0006uw-G1; Wed, 03 Sep 2025 01:13:10 -0400 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 1utfmr-0006Gv-9p for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:02 -0400 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 1utfmp-0006ZA-IB for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:01 -0400 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-638-w0irFvrSPS6gWVlv4q6h5Q-1; Wed, 03 Sep 2025 01:11:54 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 8B723195608E; Wed, 3 Sep 2025 05:11:53 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 88F9619560B1; Wed, 3 Sep 2025 05:11:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876317; 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=mW0ivbCeARcW77uG+hGeVTu54bG1KQkuvpiyp/K2kcE=; b=Uhr3GdmYzvyv64FQ8P3IoxgrTinwRTtnOR1F+xzhuNTDXZWUmhYZaNczComj5pVlA4X5ol 3fUNX0q9Zr5stQ+LU6upLUMj3qJml3XTlvDstbPthlj7vr+r4lEtZNOkYuM9X2a8eabN4d 8gP6LVvcpmL0TRwBoBfUWGfdrCWpNNw= X-MC-Unique: w0irFvrSPS6gWVlv4q6h5Q-1 X-Mimecast-MFC-AGG-ID: w0irFvrSPS6gWVlv4q6h5Q_1756876313 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 10/18] python: backport 'qmp-tui: Do not crash if optional dependencies are not met' Date: Wed, 3 Sep 2025 01:11:16 -0400 Message-ID: <20250903051125.3020805-11-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876400962116601 Content-Type: text/plain; charset="utf-8" Based on the discussion at https://github.com/pypa/pip/issues/9726 - even though the setuptools documentation implies that it is possible to guard script execution with optional dependency groups, this is not true in practice with the scripts generated by pip. Just do the simple thing and guard the import statements. Signed-off-by: John Snow cherry picked from commit df520dcacf9a75dd4c82ab1129768de4128b554c Signed-off-by: John Snow --- python/qemu/qmp/qmp_tui.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/python/qemu/qmp/qmp_tui.py b/python/qemu/qmp/qmp_tui.py index 562be008d5e..53ea6c59a71 100644 --- a/python/qemu/qmp/qmp_tui.py +++ b/python/qemu/qmp/qmp_tui.py @@ -21,6 +21,7 @@ import logging from logging import Handler, LogRecord import signal +import sys from typing import ( List, Optional, @@ -30,10 +31,20 @@ cast, ) =20 -from pygments import lexers -from pygments import token as Token -import urwid -import urwid_readline + +try: + from pygments import lexers + from pygments import token as Token + import urwid + import urwid_readline +except ModuleNotFoundError as exc: + print( + f"Module '{exc.name}' not found.", + "You need the optional 'tui' group: pip install qemu.qmp[tui]", + sep=3D'\n', + file=3Dsys.stderr, + ) + sys.exit(1) =20 from .error import ProtocolError from .legacy import QEMUMonitorProtocol, QMPBadPortError --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876375; cv=none; d=zohomail.com; s=zohoarc; b=S+mCthMg4TNLmWDVqp3r+RbvlSXobE9g6tUqSG5j/wqYO0/CMN9tGTXDkD0VRLH0bywrvrMvegdOMJqtf04zyzz5Oklim/LwJZlr7zB/wCLmtEszr7l/XVsDyw6tFHsjcSvcK6Bca09G3dEZgImEZ3DwIso/B3b4wRXJk2XMPzY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876375; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=fKbaHAEvTwJqmExIXUlbRePoGgZFad/G/AMh5OouNuw=; b=NYUI+cv5XKA/v7MvPhMC3gzklPPo/D2y0uUpbzDSY3p9TIs84UeMdbQpI6bguubIFlpOts0/LAjDAomdkVmwBiYZB/nZq3RrrGrIjgmS8FxJ4VQV35ZBQKB2Ug4BSwZYUh8xt/8dVrtE2+2GDx2OGqZ3VMxwCusZfOXzCOWKZzM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175687637541174.50528897679521; Tue, 2 Sep 2025 22:12:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfn7-0006MJ-BG; Wed, 03 Sep 2025 01:12:18 -0400 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 1utfmr-0006H0-Rv for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:02 -0400 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 1utfmq-0006Za-33 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:01 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-549-VzUXuVKpPcCIWbvZCsmxyg-1; Wed, 03 Sep 2025 01:11:56 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id F07131800581; Wed, 3 Sep 2025 05:11:55 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 44B8F19560A2; Wed, 3 Sep 2025 05:11:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876319; 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=fKbaHAEvTwJqmExIXUlbRePoGgZFad/G/AMh5OouNuw=; b=fdR1UXXrPRmvodTUoLAqOFJTR1BmXXlfv4tofi1LXE6m4BEcsuZAnGt6UbfpRo3A3FUkxv H/gCBfFtihQEzY3WMZpzvMw6dU0tRTpxQ8zrJVxow1qrl0lMZ0MPZ03om+U1DFXA/ae7gG vwabL8exzdEGTnY1OLxLT+Hq/uiVR9E= X-MC-Unique: VzUXuVKpPcCIWbvZCsmxyg-1 X-Mimecast-MFC-AGG-ID: VzUXuVKpPcCIWbvZCsmxyg_1756876316 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 11/18] python: backport 'Remove deprecated get_event_loop calls' Date: Wed, 3 Sep 2025 01:11:17 -0400 Message-ID: <20250903051125.3020805-12-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876376822116600 Content-Type: text/plain; charset="utf-8" This method was deprecated in 3.12 because it ordinarily should not be used from coroutines; if there is not a currently running event loop, this automatically creates a new event loop - which is usually not what you want from code that would ever run in the bottom half. In our case, we do want this behavior in two places: (1) The synchronous shim, for convenience: this allows fully sync programs to use QEMUMonitorProtocol() without needing to set up an event loop beforehand. This is intentional to fully box in the async complexities into the legacy sync shim. (2) The qmp_tui shell; instead of relying on asyncio.run to create and run an asyncio program, we need to be able to pass the current asyncio loop to urwid setup functions. For convenience, again, we create one if one is not present to simplify the creation of the TUI appliance. The remaining user of get_event_loop() was in fact one of the erroneous users that should not have been using this function: if there's no running event loop inside of a coroutine, you're in big trouble :) Signed-off-by: John Snow cherry picked from commit aa1ff9907603a3033296027e1bd021133df86ef1 Signed-off-by: John Snow --- python/qemu/qmp/legacy.py | 9 ++++++++- python/qemu/qmp/qmp_tui.py | 7 ++++++- python/tests/protocol.py | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/python/qemu/qmp/legacy.py b/python/qemu/qmp/legacy.py index c8d0a29b56f..735d42971e9 100644 --- a/python/qemu/qmp/legacy.py +++ b/python/qemu/qmp/legacy.py @@ -86,7 +86,14 @@ def __init__(self, "server argument should be False when passing a socket") =20 self._qmp =3D QMPClient(nickname) - self._aloop =3D asyncio.get_event_loop() + + try: + self._aloop =3D asyncio.get_running_loop() + except RuntimeError: + # No running loop; since this is a sync shim likely to be + # used in fully sync programs, create one if neccessary. + self._aloop =3D asyncio.get_event_loop_policy().get_event_loop= () + self._address =3D address self._timeout: Optional[float] =3D None =20 diff --git a/python/qemu/qmp/qmp_tui.py b/python/qemu/qmp/qmp_tui.py index 53ea6c59a71..12bdc17c99e 100644 --- a/python/qemu/qmp/qmp_tui.py +++ b/python/qemu/qmp/qmp_tui.py @@ -388,7 +388,12 @@ def run(self, debug: bool =3D False) -> None: screen =3D urwid.raw_display.Screen() screen.set_terminal_properties(256) =20 - self.aloop =3D asyncio.get_event_loop() + try: + self.aloop =3D asyncio.get_running_loop() + except RuntimeError: + # No running asyncio event loop. Create one if necessary. + self.aloop =3D asyncio.get_event_loop_policy().get_event_loop() + self.aloop.set_debug(debug) =20 # Gracefully handle SIGTERM and SIGINT signals diff --git a/python/tests/protocol.py b/python/tests/protocol.py index c254c77b176..e565802516d 100644 --- a/python/tests/protocol.py +++ b/python/tests/protocol.py @@ -227,7 +227,7 @@ def async_test(async_test_method): Decorator; adds SetUp and TearDown to async tests. """ async def _wrapper(self, *args, **kwargs): - loop =3D asyncio.get_event_loop() + loop =3D asyncio.get_running_loop() loop.set_debug(True) =20 await self._asyncSetUp() --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876664; cv=none; d=zohomail.com; s=zohoarc; b=VjLNN8h3GNxR6sw2yRwaEIAmsu5BibRW85FAKkGCo+neX51qS/8DssoNiZjv4exrjMaTIZltxXXiDj6Orw+K9o7XXuYO6NqkYllVRcLOS94vqKCg2VAY6KHGlUJ1UIYUliJq6Qrm31ZO6fYMjzSleosq0+i8RCA6mSn8Gct5UAs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876664; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=DMrZcYYh3K6amIjIAiIGx9VdKqeKnCNubcsS4x5vvUQ=; b=Vn0dm2y9wO2hKsjbe50a4Ht0FhnO+rLLAmalRlfPIfFTEBanksqXjwOsakHijqhEdNZVnr8yvZh62P5mGjpRJTHalRVzBphYkfw0uJZrv7yt/DAozsZUFiYTYYTL42kaFFoCPVqYaC+R/CRDY/arAwfoRDuOzzJ/1NxSJHtJDQs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876664047193.39051251535966; Tue, 2 Sep 2025 22:17:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfpH-0008UP-C4; Wed, 03 Sep 2025 01:14:37 -0400 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 1utfmz-0006KW-OB for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:11 -0400 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 1utfmu-0006ae-Rc for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:07 -0400 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-15-MPnl8GT4O7iNyHLM2QLUUA-1; Wed, 03 Sep 2025 01:12:00 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 E67911956096; Wed, 3 Sep 2025 05:11:59 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CD1C319560A2; Wed, 3 Sep 2025 05:11:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876324; 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=DMrZcYYh3K6amIjIAiIGx9VdKqeKnCNubcsS4x5vvUQ=; b=eECGTiI60d9JEkFhG51hhdRhcK94RrIFD8llkN4rXVxMzNcHViXM5qbP6gwbJkCJnBMhRx JiCqsBTzEscfP922FXxNPjF0gUOfKBoTW6qhMeuTM53WH8AzLP7MF/vuGjxsjfZ4Z/3JpE Kb2YbCNuow9YzNhk0tFKE7nq3EJ5t0s= X-MC-Unique: MPnl8GT4O7iNyHLM2QLUUA-1 X-Mimecast-MFC-AGG-ID: MPnl8GT4O7iNyHLM2QLUUA_1756876320 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf , "Richard W.M. Jones" Subject: [PATCH v2 12/18] python: backport 'avoid creating additional event loops per thread' Date: Wed, 3 Sep 2025 01:11:18 -0400 Message-ID: <20250903051125.3020805-13-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876665081124100 This commit is two backports squashed into one to avoid regressions. python: *really* remove get_event_loop A prior commit, aa1ff990, switched away from using get_event_loop *by default*, but this is not good enough to avoid deprecation warnings as `asyncio.get_event_loop_policy().get_event_loop()` is *also* deprecated. Replace this mechanism with explicit calls to asyncio.get_new_loop() and revise the cleanup mechanisms in __del__ to match. python: avoid creating additional event loops per thread "Too hasty by far!", commit 21ce2ee4 attempted to avoid deprecated behavior altogether by calling new_event_loop() directly if there was no loop currently running, but this has the unfortunate side effect of potentially creating multiple event loops per thread if tests instantiate multiple QMP connections in a single thread. This behavior is apparently not well-defined and causes problems in some, but not all, combinations of Python interpreter version and platform environment. Partially revert to Daniel Berrange's original patch, which calls get_event_loop and simply suppresses the deprecation warning in Python<=3D3.13. This time, however, additionally register new loops created with new_event_loop() so that future calls to get_event_loop() will return the loop already created. Reported-by: Richard W.M. Jones Reported-by: Daniel P. Berrang=C3=A9 Signed-off-by: John Snow cherry picked from commit 21ce2ee4f2df87efe84a27b9c5112487f4670622 cherry picked from commit c08fb82b38212956ccffc03fc6d015c3979f42fe Signed-off-by: John Snow --- python/qemu/qmp/legacy.py | 46 +++++++++++++++++++++++--------------- python/qemu/qmp/qmp_tui.py | 10 ++------- python/qemu/qmp/util.py | 27 ++++++++++++++++++++++ 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/python/qemu/qmp/legacy.py b/python/qemu/qmp/legacy.py index 735d42971e9..e46695ae2c8 100644 --- a/python/qemu/qmp/legacy.py +++ b/python/qemu/qmp/legacy.py @@ -38,6 +38,7 @@ from .error import QMPError from .protocol import Runstate, SocketAddrT from .qmp_client import QMPClient +from .util import get_or_create_event_loop =20 =20 #: QMPMessage is an entire QMP message of any kind. @@ -86,17 +87,13 @@ def __init__(self, "server argument should be False when passing a socket") =20 self._qmp =3D QMPClient(nickname) - - try: - self._aloop =3D asyncio.get_running_loop() - except RuntimeError: - # No running loop; since this is a sync shim likely to be - # used in fully sync programs, create one if neccessary. - self._aloop =3D asyncio.get_event_loop_policy().get_event_loop= () - self._address =3D address self._timeout: Optional[float] =3D None =20 + # This is a sync shim intended for use in fully synchronous + # programs. Create and set an event loop if necessary. + self._aloop =3D get_or_create_event_loop() + if server: assert not isinstance(self._address, socket.socket) self._sync(self._qmp.start_server(self._address)) @@ -313,17 +310,30 @@ def send_fd_scm(self, fd: int) -> None: self._qmp.send_fd_scm(fd) =20 def __del__(self) -> None: - if self._qmp.runstate =3D=3D Runstate.IDLE: - return + if self._qmp.runstate !=3D Runstate.IDLE: + self._qmp.logger.warning( + "QEMUMonitorProtocol object garbage collected without a pr= ior " + "call to close()" + ) =20 if not self._aloop.is_running(): - self.close() - else: - # Garbage collection ran while the event loop was running. - # Nothing we can do about it now, but if we don't raise our - # own error, the user will be treated to a lot of traceback - # they might not understand. + if self._qmp.runstate !=3D Runstate.IDLE: + # If the user neglected to close the QMP session and we + # are not currently running in an asyncio context, we + # have the opportunity to close the QMP session. If we + # do not do this, the error messages presented over + # dangling async resources may not make any sense to the + # user. + self.close() + + if self._qmp.runstate !=3D Runstate.IDLE: + # If QMP is still not quiesced, it means that the garbage + # collector ran from a context within the event loop and we + # are simply too late to take any corrective action. Raise + # our own error to give meaningful feedback to the user in + # order to prevent pages of asyncio stacktrace jargon. raise QMPError( - "QEMUMonitorProtocol.close()" - " was not called before object was garbage collected" + "QEMUMonitorProtocol.close() was not called before object = was " + "garbage collected, and could not be closed due to GC runn= ing " + "in the event loop" ) diff --git a/python/qemu/qmp/qmp_tui.py b/python/qemu/qmp/qmp_tui.py index 12bdc17c99e..d946c205131 100644 --- a/python/qemu/qmp/qmp_tui.py +++ b/python/qemu/qmp/qmp_tui.py @@ -51,7 +51,7 @@ from .message import DeserializationError, Message, UnexpectedTypeError from .protocol import ConnectError, Runstate from .qmp_client import ExecInterruptedError, QMPClient -from .util import pretty_traceback +from .util import get_or_create_event_loop, pretty_traceback =20 =20 # The name of the signal that is used to update the history list @@ -387,13 +387,7 @@ def run(self, debug: bool =3D False) -> None: """ screen =3D urwid.raw_display.Screen() screen.set_terminal_properties(256) - - try: - self.aloop =3D asyncio.get_running_loop() - except RuntimeError: - # No running asyncio event loop. Create one if necessary. - self.aloop =3D asyncio.get_event_loop_policy().get_event_loop() - + self.aloop =3D get_or_create_event_loop() self.aloop.set_debug(debug) =20 # Gracefully handle SIGTERM and SIGINT signals diff --git a/python/qemu/qmp/util.py b/python/qemu/qmp/util.py index 0b3e781373d..47ec39a8b5e 100644 --- a/python/qemu/qmp/util.py +++ b/python/qemu/qmp/util.py @@ -10,6 +10,7 @@ import sys import traceback from typing import TypeVar, cast +import warnings =20 =20 T =3D TypeVar('T') @@ -20,6 +21,32 @@ # -------------------------- =20 =20 +def get_or_create_event_loop() -> asyncio.AbstractEventLoop: + """ + Return this thread's current event loop, or create a new one. + + This function behaves similarly to asyncio.get_event_loop() in + Python<=3D3.13, where if there is no event loop currently associated + with the current context, it will create and register one. It should + generally not be used in any asyncio-native applications. + """ + try: + with warnings.catch_warnings(): + # Python <=3D 3.13 will trigger deprecation warnings if no + # event loop is set, but will create and set a new loop. + warnings.simplefilter("ignore") + loop =3D asyncio.get_event_loop() + except RuntimeError: + # Python 3.14+: No event loop set for this thread, + # create and set one. + loop =3D asyncio.new_event_loop() + # Set this loop as the current thread's loop, to be returned + # by calls to get_event_loop() in the future. + asyncio.set_event_loop(loop) + + return loop + + async def flush(writer: asyncio.StreamWriter) -> None: """ Utility function to ensure a StreamWriter is *fully* drained. --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876667; cv=none; d=zohomail.com; s=zohoarc; b=cAqZzYcZkD2M1GToPPz1no4cU8D1QgUTVWJ3g0D/seUTPdtqB/mNiGzLogVVbbPUl+TU39UyVwA3EWmBF2p7xlL3NWhfRPaI8jTAhR0ucOKmdRdoW20rlqg0L5qHOffxYZRBWziQTPgUKPuaP1TEhSvFMD/lWCW4qvHk9lYRHwQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876667; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=TxO4lBmMxGa04h84r5x3imc7ofF7t8ngOEeqErnHQGE=; b=XNoXl8Iv5q9RrR1MGF1aBGltp152InUg8uKZqWB4uah5nVKZeqlCZ2DkO9EETnSp5x/xLIW5X+yFL22WUxE+zn+67r7aWzi/fXkbsIU5k8oDRGGEK2v/dK9CSPicLz85ARNjATyjkP59NrJ7lARFuJ3FAVfgVBE3Lljj0V2sbl4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876667791674.1362959301312; Tue, 2 Sep 2025 22:17:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfp7-00087S-N9; Wed, 03 Sep 2025 01:14:22 -0400 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 1utfn1-0006KY-3G for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:11 -0400 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 1utfmv-0006b1-N3 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:10 -0400 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-359-tcWwXkV0Ot6aYmkssSbqTQ-1; Wed, 03 Sep 2025 01:12:03 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 2D48619560A5; Wed, 3 Sep 2025 05:12:02 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 44F1119560B1; Wed, 3 Sep 2025 05:12:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876324; 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=TxO4lBmMxGa04h84r5x3imc7ofF7t8ngOEeqErnHQGE=; b=f/ui10ZKnyv77PMlKENIZOeNIC18VgEYi2iEseBe0AHvZ78zxOUSX8O+5FkWBE31ZWMx7x 6KtzWYv5Qfo+0PreKiumnvrqsIeMmxesEWlGVGZoXaVsBSlhzsGiHm/i4sVJHtzT9EXtlo 1LL7GWkwtflXQAAYKMzQIpP330PR9Hg= X-MC-Unique: tcWwXkV0Ot6aYmkssSbqTQ-1 X-Mimecast-MFC-AGG-ID: tcWwXkV0Ot6aYmkssSbqTQ_1756876322 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 13/18] python: synchronize qemu.qmp documentation Date: Wed, 3 Sep 2025 01:11:19 -0400 Message-ID: <20250903051125.3020805-14-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876668754116600 This patch collects comments and documentation changes from many commits in the python-qemu-qmp repository; bringing the qemu.git copy in bit-identical alignment with the standalone library *except* for several copyright messages that reference the "LICENSE" file which is, for QEMU, named "COPYING" instead and are therefore left unchanged. Signed-off-by: John Snow --- python/qemu/qmp/__init__.py | 3 +- python/qemu/qmp/events.py | 35 +++++++--- python/qemu/qmp/legacy.py | 4 +- python/qemu/qmp/message.py | 10 ++- python/qemu/qmp/models.py | 8 +-- python/qemu/qmp/protocol.py | 37 ++++++---- python/qemu/qmp/qmp_client.py | 117 +++++++++++++++++++++++-------- python/qemu/qmp/qmp_shell.py | 128 ++++++++++++++++++++++++++-------- python/qemu/qmp/util.py | 9 ++- 9 files changed, 264 insertions(+), 87 deletions(-) diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py index 69190d057a5..058139dc3ca 100644 --- a/python/qemu/qmp/__init__.py +++ b/python/qemu/qmp/__init__.py @@ -39,7 +39,8 @@ logging.getLogger('qemu.qmp').addHandler(logging.NullHandler()) =20 =20 -# The order of these fields impact the Sphinx documentation order. +# IMPORTANT: When modifying this list, update the Sphinx overview docs. +# Anything visible in the qemu.qmp namespace should be on the overview pag= e. __all__ =3D ( # Classes, most to least important 'QMPClient', diff --git a/python/qemu/qmp/events.py b/python/qemu/qmp/events.py index 66583496192..cfb5f0ac621 100644 --- a/python/qemu/qmp/events.py +++ b/python/qemu/qmp/events.py @@ -12,7 +12,14 @@ ---------------------- =20 In all of the following examples, we assume that we have a `QMPClient` -instantiated named ``qmp`` that is already connected. +instantiated named ``qmp`` that is already connected. For example: + +.. code:: python + + from qemu.qmp import QMPClient + + qmp =3D QMPClient('example-vm') + await qmp.connect('127.0.0.1', 1234) =20 =20 `listener()` context blocks with one name @@ -87,7 +94,9 @@ event =3D listener.get() print(f"Event arrived: {event['event']}") =20 -This event stream will never end, so these blocks will never terminate. +This event stream will never end, so these blocks will never +terminate. Even if the QMP connection errors out prematurely, this +listener will go silent without raising an error. =20 =20 Using asyncio.Task to concurrently retrieve events @@ -227,16 +236,20 @@ async def print_events(listener): .. code:: python =20 await qmp.execute('stop') - qmp.events.clear() + discarded =3D qmp.events.clear() await qmp.execute('cont') event =3D await qmp.events.get() assert event['event'] =3D=3D 'RESUME' + assert discarded[0]['event'] =3D=3D 'STOP' =20 `EventListener` objects are FIFO queues. If events are not consumed, they will remain in the queue until they are witnessed or discarded via `clear()`. FIFO queues will be drained automatically upon leaving a context block, or when calling `remove_listener()`. =20 +Any events removed from the queue in this fashion will be returned by +the clear call. + =20 Accessing listener history ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -350,6 +363,12 @@ def filter(event: Message) -> bool: break =20 =20 +Note that in the above example, we explicitly wait on jobA to conclude +first, and then wait for jobB to do the same. All we have guaranteed is +that the code that waits for jobA will not accidentally consume the +event intended for the jobB waiter. + + Extending the `EventListener` class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =20 @@ -407,13 +426,13 @@ def accept(self, event) -> bool: These interfaces are not ones I am sure I will keep or otherwise modify heavily. =20 -qmp.listener()=E2=80=99s type signature +qmp.listen()=E2=80=99s type signature ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =20 -`listener()` does not return anything, because it was assumed the caller +`listen()` does not return anything, because it was assumed the caller already had a handle to the listener. However, for -``qmp.listener(EventListener())`` forms, the caller will not have saved -a handle to the listener. +``qmp.listen(EventListener())`` forms, the caller will not have saved a +handle to the listener. =20 Because this function can accept *many* listeners, I found it hard to accurately type in a way where it could be used in both =E2=80=9Cone=E2=80= =9D or =E2=80=9Cmany=E2=80=9D @@ -633,7 +652,7 @@ class Events: def __init__(self) -> None: self._listeners: List[EventListener] =3D [] =20 - #: Default, all-events `EventListener`. + #: Default, all-events `EventListener`. See `qmp.events` for more = info. self.events: EventListener =3D EventListener() self.register_listener(self.events) =20 diff --git a/python/qemu/qmp/legacy.py b/python/qemu/qmp/legacy.py index e46695ae2c8..060ed0eb9d4 100644 --- a/python/qemu/qmp/legacy.py +++ b/python/qemu/qmp/legacy.py @@ -293,8 +293,8 @@ def settimeout(self, timeout: Optional[float]) -> None: """ Set the timeout for QMP RPC execution. =20 - This timeout affects the `cmd`, `cmd_obj`, and `command` methods. - The `accept`, `pull_event` and `get_event` methods have their + This timeout affects the `cmd`, `cmd_obj`, and `cmd_raw` methods. + The `accept`, `pull_event` and `get_events` methods have their own configurable timeouts. =20 :param timeout: diff --git a/python/qemu/qmp/message.py b/python/qemu/qmp/message.py index c2e9dd0dd54..dabb8ec360e 100644 --- a/python/qemu/qmp/message.py +++ b/python/qemu/qmp/message.py @@ -28,7 +28,8 @@ class Message(MutableMapping[str, object]): be instantiated from either another mapping (like a `dict`), or from raw `bytes` that still need to be deserialized. =20 - Once instantiated, it may be treated like any other MutableMapping:: + Once instantiated, it may be treated like any other + :py:obj:`~collections.abc.MutableMapping`:: =20 >>> msg =3D Message(b'{"hello": "world"}') >>> assert msg['hello'] =3D=3D 'world' @@ -50,12 +51,19 @@ class Message(MutableMapping[str, object]): >>> dict(msg) {'hello': 'world'} =20 + Or pretty-printed:: + + >>> print(str(msg)) + { + "hello": "world" + } =20 :param value: Initial value, if any. :param eager: When `True`, attempt to serialize or deserialize the initial value immediately, so that conversion exceptions are raised during the call to ``__init__()``. + """ # pylint: disable=3Dtoo-many-ancestors =20 diff --git a/python/qemu/qmp/models.py b/python/qemu/qmp/models.py index da52848d5a7..7e0d0baf038 100644 --- a/python/qemu/qmp/models.py +++ b/python/qemu/qmp/models.py @@ -54,7 +54,7 @@ def __repr__(self) -> str: =20 class Greeting(Model): """ - Defined in qmp-spec.rst, section "Server Greeting". + Defined in `interop/qmp-spec`, "Server Greeting" section. =20 :param raw: The raw Greeting object. :raise KeyError: If any required fields are absent. @@ -82,7 +82,7 @@ def _asdict(self) -> Dict[str, object]: =20 class QMPGreeting(Model): """ - Defined in qmp-spec.rst, section "Server Greeting". + Defined in `interop/qmp-spec`, "Server Greeting" section. =20 :param raw: The raw QMPGreeting object. :raise KeyError: If any required fields are absent. @@ -104,7 +104,7 @@ def __init__(self, raw: Mapping[str, Any]): =20 class ErrorResponse(Model): """ - Defined in qmp-spec.rst, section "Error". + Defined in `interop/qmp-spec`, "Error" section. =20 :param raw: The raw ErrorResponse object. :raise KeyError: If any required fields are absent. @@ -126,7 +126,7 @@ def __init__(self, raw: Mapping[str, Any]): =20 class ErrorInfo(Model): """ - Defined in qmp-spec.rst, section "Error". + Defined in `interop/qmp-spec`, "Error" section. =20 :param raw: The raw ErrorInfo object. :raise KeyError: If any required fields are absent. diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index 4d8a39f014b..219d092a792 100644 --- a/python/qemu/qmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -79,6 +79,12 @@ class ConnectError(QMPError): This Exception always wraps a "root cause" exception that can be interrogated for additional information. =20 + For example, when connecting to a non-existent socket:: + + await qmp.connect('not_found.sock') + # ConnectError: Failed to establish connection: + # [Errno 2] No such file or directory + :param error_message: Human-readable string describing the error. :param exc: The root-cause exception. """ @@ -102,8 +108,8 @@ class StateError(QMPError): An API command (connect, execute, etc) was issued at an inappropriate = time. =20 This error is raised when a command like - :py:meth:`~AsyncProtocol.connect()` is issued at an inappropriate - time. + :py:meth:`~AsyncProtocol.connect()` is called when the client is + already connected. =20 :param error_message: Human-readable string describing the state viola= tion. :param state: The actual `Runstate` seen at the time of the violation. @@ -298,7 +304,7 @@ def runstate(self) -> Runstate: @upper_half async def runstate_changed(self) -> Runstate: """ - Wait for the `runstate` to change, then return that runstate. + Wait for the `runstate` to change, then return that `Runstate`. """ await self._runstate_event.wait() return self.runstate @@ -312,9 +318,9 @@ async def start_server_and_accept( """ Accept a connection and begin processing message queues. =20 - If this call fails, `runstate` is guaranteed to be set back to `ID= LE`. - This method is precisely equivalent to calling `start_server()` - followed by `accept()`. + If this call fails, `runstate` is guaranteed to be set back to + `IDLE`. This method is precisely equivalent to calling + `start_server()` followed by :py:meth:`~AsyncProtocol.accept()`. =20 :param address: Address to listen on; UNIX socket path or TCP address/port. @@ -327,7 +333,8 @@ async def start_server_and_accept( This exception will wrap a more concrete one. In most cases, the wrapped exception will be `OSError` or `EOFError`. If a protocol-level failure occurs while establishing a new - session, the wrapped error may also be an `QMPError`. + session, the wrapped error may also be a `QMPError`. + """ await self.start_server(address, ssl) await self.accept() @@ -343,8 +350,8 @@ async def start_server(self, address: SocketAddrT, This method starts listening for an incoming connection, but does not block waiting for a peer. This call will return immediately after binding and listening on a socket. A later - call to `accept()` must be made in order to finalize the - incoming connection. + call to :py:meth:`~AsyncProtocol.accept()` must be made in order + to finalize the incoming connection. =20 :param address: Address to listen on; UNIX socket path or TCP address/port. @@ -367,10 +374,12 @@ async def accept(self) -> None: """ Accept an incoming connection and begin processing message queues. =20 - If this call fails, `runstate` is guaranteed to be set back to `ID= LE`. + Used after a previous call to `start_server()` to accept an + incoming connection. If this call fails, `runstate` is + guaranteed to be set back to `IDLE`. =20 :raise StateError: When the `Runstate` is not `CONNECTING`. - :raise QMPError: When `start_server()` was not called yet. + :raise QMPError: When `start_server()` was not called first. :raise ConnectError: When a connection or session cannot be established. =20 @@ -423,7 +432,11 @@ async def disconnect(self) -> None: If there was an exception that caused the reader/writers to terminate prematurely, it will be raised here. =20 - :raise Exception: When the reader or writer terminate unexpectedly. + :raise Exception: + When the reader or writer terminate unexpectedly. You can + expect to see `EOFError` if the server hangs up, or + `OSError` for connection-related issues. If there was a QMP + protocol-level problem, `ProtocolError` will be seen. """ self.logger.debug("disconnect() called.") self._schedule_disconnect() diff --git a/python/qemu/qmp/qmp_client.py b/python/qemu/qmp/qmp_client.py index d826331b6d5..8beccfe29d3 100644 --- a/python/qemu/qmp/qmp_client.py +++ b/python/qemu/qmp/qmp_client.py @@ -70,6 +70,17 @@ class ExecuteError(QMPError): """ Exception raised by `QMPClient.execute()` on RPC failure. =20 + This exception is raised when the server received, interpreted, and + replied to a command successfully; but the command itself returned a + failure status. + + For example:: + + await qmp.execute('block-dirty-bitmap-add', + {'node': 'foo', 'name': 'my_bitmap'}) + # qemu.qmp.qmp_client.ExecuteError: + # Cannot find device=3D'foo' nor node-name=3D'foo' + :param error_response: The RPC error response object. :param sent: The sent RPC message that caused the failure. :param received: The raw RPC error reply received. @@ -99,9 +110,22 @@ class ExecInterruptedError(QMPError): =20 This error is raised when an `execute()` statement could not be completed. This can occur because the connection itself was - terminated before a reply was received. + terminated before a reply was received. The true cause of the + interruption will be available via `disconnect()`. =20 - The true cause of the interruption will be available via `disconnect()= `. + The QMP protocol does not make it possible to know if a command + succeeded or failed after such an event; the client will need to + query the server to determine the state of the server on a + case-by-case basis. + + For example, ECONNRESET might look like this:: + + try: + await qmp.execute('query-block') + # ExecInterruptedError: Disconnected + except ExecInterruptedError: + await qmp.disconnect() + # ConnectionResetError: [Errno 104] Connection reset by peer """ =20 =20 @@ -162,13 +186,14 @@ def __init__(self, error_message: str, msg: Message, = sent: Message): =20 =20 class QMPClient(AsyncProtocol[Message], Events): - """ - Implements a QMP client connection. + """Implements a QMP client connection. =20 - QMP can be used to establish a connection as either the transport - client or server, though this class always acts as the QMP client. + `QMPClient` can be used to either connect or listen to a QMP server, + but always acts as the QMP client. =20 - :param name: Optional nickname for the connection, used for logging. + :param name: + Optional nickname for the connection, used to differentiate + instances when logging. =20 :param readbuflen: The maximum buffer length for reads and writes to and from the QMP @@ -178,14 +203,21 @@ class QMPClient(AsyncProtocol[Message], Events): =20 Basic script-style usage looks like this:: =20 - qmp =3D QMPClient('my_virtual_machine_name') - await qmp.connect(('127.0.0.1', 1234)) - ... - res =3D await qmp.execute('block-query') - ... - await qmp.disconnect() + import asyncio + from qemu.qmp import QMPClient =20 - Basic async client-style usage looks like this:: + async def main(): + qmp =3D QMPClient('my_virtual_machine_name') + await qmp.connect(('127.0.0.1', 1234)) + ... + res =3D await qmp.execute('query-block') + ... + await qmp.disconnect() + + asyncio.run(main()) + + A more advanced example that starts to take advantage of asyncio + might look like this:: =20 class Client: def __init__(self, name: str): @@ -205,6 +237,7 @@ async def run(self, address=3D'/tmp/qemu.socket'): await self.disconnect() =20 See `qmp.events` for more detail on event handling patterns. + """ #: Logger object used for debugging messages. logger =3D logging.getLogger(__name__) @@ -224,10 +257,12 @@ def __init__( Events.__init__(self) =20 #: Whether or not to await a greeting after establishing a connect= ion. + #: Defaults to True; QGA servers expect this to be False. self.await_greeting: bool =3D True =20 - #: Whether or not to perform capabilities negotiation upon connect= ion. - #: Implies `await_greeting`. + #: Whether or not to perform capabilities negotiation upon + #: connection. Implies `await_greeting`. Defaults to True; QGA + #: servers expect this to be False. self.negotiate: bool =3D True =20 # Cached Greeting, if one was awaited. @@ -244,7 +279,13 @@ def __init__( =20 @property def greeting(self) -> Optional[Greeting]: - """The `Greeting` from the QMP server, if any.""" + """ + The `Greeting` from the QMP server, if any. + + Defaults to ``None``, and will be set after a greeting is + received during the connection process. It is reset at the start + of each connection attempt. + """ return self._greeting =20 @upper_half @@ -385,7 +426,7 @@ async def _on_message(self, msg: Message) -> None: # This is very likely a server parsing error. # It doesn't inherently belong to any pending execution. # Instead of performing clever recovery, just terminate. - # See "NOTE" in qmp-spec.rst, section "Error". + # See "NOTE" in interop/qmp-spec, "Error" section. raise ServerParseError( ("Server sent an error response without an ID, " "but there are no ID-less executions pending. " @@ -393,7 +434,7 @@ async def _on_message(self, msg: Message) -> None: msg ) =20 - # qmp-spec.rst, section "Commands Responses": + # qmp-spec.rst, "Commands Responses" section: # 'Clients should drop all the responses # that have an unknown "id" field.' self.logger.log( @@ -566,7 +607,7 @@ async def _raw( @require(Runstate.RUNNING) async def execute_msg(self, msg: Message) -> object: """ - Execute a QMP command and return its value. + Execute a QMP command on the server and return its value. =20 :param msg: The QMP `Message` to execute. =20 @@ -578,7 +619,9 @@ async def execute_msg(self, msg: Message) -> object: If the QMP `Message` does not have either the 'execute' or 'exec-oob' fields set. :raise ExecuteError: When the server returns an error response. - :raise ExecInterruptedError: if the connection was terminated earl= y. + :raise ExecInterruptedError: + If the connection was disrupted before + receiving a reply from the server. """ if not ('execute' in msg or 'exec-oob' in msg): raise ValueError("Requires 'execute' or 'exec-oob' message") @@ -617,9 +660,11 @@ def make_execute_msg(cls, cmd: str, =20 :param cmd: QMP command name. :param arguments: Arguments (if any). Must be JSON-serializable. - :param oob: If `True`, execute "out of band". + :param oob: + If `True`, execute "out of band". See `interop/qmp-spec` + section "Out-of-band execution". =20 - :return: An executable QMP `Message`. + :return: A QMP `Message` that can be executed with `execute_msg()`. """ msg =3D Message({'exec-oob' if oob else 'execute': cmd}) if arguments is not None: @@ -631,18 +676,22 @@ async def execute(self, cmd: str, arguments: Optional[Mapping[str, object]] =3D None, oob: bool =3D False) -> object: """ - Execute a QMP command and return its value. + Execute a QMP command on the server and return its value. =20 :param cmd: QMP command name. :param arguments: Arguments (if any). Must be JSON-serializable. - :param oob: If `True`, execute "out of band". + :param oob: + If `True`, execute "out of band". See `interop/qmp-spec` + section "Out-of-band execution". =20 :return: The command execution return value from the server. The type of object returned depends on the command that was issued, though most in QEMU return a `dict`. :raise ExecuteError: When the server returns an error response. - :raise ExecInterruptedError: if the connection was terminated earl= y. + :raise ExecInterruptedError: + If the connection was disrupted before + receiving a reply from the server. """ msg =3D self.make_execute_msg(cmd, arguments, oob=3Doob) return await self.execute_msg(msg) @@ -650,8 +699,20 @@ async def execute(self, cmd: str, @upper_half @require(Runstate.RUNNING) def send_fd_scm(self, fd: int) -> None: - """ - Send a file descriptor to the remote via SCM_RIGHTS. + """Send a file descriptor to the remote via SCM_RIGHTS. + + This method does not close the file descriptor. + + :param fd: The file descriptor to send to QEMU. + + This is an advanced feature of QEMU where file descriptors can + be passed from client to server. This is usually used as a + security measure to isolate the QEMU process from being able to + open its own files. See the QMP commands ``getfd`` and + ``add-fd`` for more information. + + See `socket.socket.sendmsg` for more information on the Python + implementation for sending file descriptors over a UNIX socket. """ assert self._writer is not None sock =3D self._writer.transport.get_extra_info('socket') diff --git a/python/qemu/qmp/qmp_shell.py b/python/qemu/qmp/qmp_shell.py index c923ff09e1f..f8188005685 100644 --- a/python/qemu/qmp/qmp_shell.py +++ b/python/qemu/qmp/qmp_shell.py @@ -10,9 +10,15 @@ # =20 """ -Low-level QEMU shell on top of QMP. +qmp-shell - An interactive QEMU shell powered by QMP =20 -usage: qmp-shell [-h] [-H] [-N] [-v] [-p] qmp_server +qmp-shell offers a simple shell with a convenient shorthand syntax as an +alternative to typing JSON by hand. This syntax is not standardized and +is not meant to be used as a scriptable interface. This shorthand *may* +change incompatibly in the future, and it is strongly encouraged to use +the QMP library to provide API-stable scripting when needed. + +usage: qmp-shell [-h] [-H] [-v] [-p] [-l LOGFILE] [-N] qmp_server =20 positional arguments: qmp_server < UNIX socket path | TCP address:port > @@ -20,41 +26,52 @@ optional arguments: -h, --help show this help message and exit -H, --hmp Use HMP interface - -N, --skip-negotiation - Skip negotiate (for qemu-ga) -v, --verbose Verbose (echo commands sent and received) -p, --pretty Pretty-print JSON + -l LOGFILE, --logfile LOGFILE + Save log of all QMP messages to PATH + -N, --skip-negotiation + Skip negotiate (for qemu-ga) =20 +Usage +----- =20 -Start QEMU with: +First, start QEMU with:: =20 -# qemu [...] -qmp unix:./qmp-sock,server + > qemu [...] -qmp unix:./qmp-sock,server=3Don[,wait=3Doff] =20 -Run the shell: +Then run the shell, passing the address of the socket:: =20 -$ qmp-shell ./qmp-sock + > qmp-shell ./qmp-sock =20 -Commands have the following format: +Syntax +------ =20 - < command-name > [ arg-name1=3Darg1 ] ... [ arg-nameN=3DargN ] +Commands have the following format:: =20 -For example: + < command-name > [ arg-name1=3Darg1 ] ... [ arg-nameN=3DargN ] =20 -(QEMU) device_add driver=3De1000 id=3Dnet1 -{'return': {}} -(QEMU) +For example, to add a network device:: =20 -key=3Dvalue pairs also support Python or JSON object literal subset notati= ons, -without spaces. Dictionaries/objects {} are supported as are arrays []. + (QEMU) device_add driver=3De1000 id=3Dnet1 + {'return': {}} + (QEMU) =20 - example-command arg-name1=3D{'key':'value','obj'=3D{'prop':"value"}} +key=3Dvalue pairs support either Python or JSON object literal notations, +**without spaces**. Dictionaries/objects ``{}`` are supported, as are +arrays ``[]``:: =20 -Both JSON and Python formatting should work, including both styles of -string literal quotes. Both paradigms of literal values should work, -including null/true/false for JSON and None/True/False for Python. + example-command arg-name1=3D{'key':'value','obj'=3D{'prop':"value"}} =20 +Either JSON or Python formatting for compound values works, including +both styles of string literal quotes (either single or double +quotes). Both paradigms of literal values are accepted, including +``null/true/false`` for JSON and ``None/True/False`` for Python. =20 -Transactions have the following multi-line format: +Transactions +------------ + +Transactions have the following multi-line format:: =20 transaction( action-name1 [ arg-name1=3Darg1 ] ... [arg-nameN=3DargN ] @@ -62,11 +79,11 @@ action-nameN [ arg-name1=3Darg1 ] ... [arg-nameN=3DargN ] ) =20 -One line transactions are also supported: +One line transactions are also supported:: =20 transaction( action-name1 ... ) =20 -For example: +For example:: =20 (QEMU) transaction( TRANS> block-dirty-bitmap-add node=3Ddrive0 name=3Dbitmap1 @@ -75,9 +92,35 @@ {"return": {}} (QEMU) =20 -Use the -v and -p options to activate the verbose and pretty-print options, -which will echo back the properly formatted JSON-compliant QMP that is bei= ng -sent to QEMU, which is useful for debugging and documentation generation. +Commands +-------- + +Autocomplete of command names using is supported. Pressing +at a blank CLI prompt will show you a list of all available commands +that the connected QEMU instance supports. + +For documentation on QMP commands and their arguments, please see +`qmp ref`. + +Events +------ + +qmp-shell will display events received from the server, but this version +does not do so asynchronously. To check for new events from the server, +press on a blank line:: + + (QEMU) =E2=8F=8E + {'timestamp': {'seconds': 1660071944, 'microseconds': 184667}, + 'event': 'STOP'} + +Display options +--------------- + +Use the -v and -p options to activate the verbose and pretty-print +options, which will echo back the properly formatted JSON-compliant QMP +that is being sent to QEMU. This is useful for debugging to see the +wire-level QMP data being exchanged, and generating output for use in +writing documentation for QEMU. """ =20 import argparse @@ -525,6 +568,8 @@ def common_parser() -> argparse.ArgumentParser: help=3D'Pretty-print JSON') parser.add_argument('-l', '--logfile', help=3D'Save log of all QMP messages to PATH') + # NOTE: When changing arguments, update both this module docstring + # and the manpage synopsis in docs/man/qmp_shell.rst. return parser =20 =20 @@ -567,8 +612,35 @@ def main() -> None: =20 def main_wrap() -> None: """ - qmp-shell-wrap entry point: parse command line arguments and - start the REPL. + qmp-shell-wrap - QEMU + qmp-shell launcher utility + + Launch QEMU and connect to it with `qmp-shell` in a single command. + CLI arguments will be forwarded to qemu, with additional arguments + added to allow `qmp-shell` to then connect to the recently launched + QEMU instance. + + usage: qmp-shell-wrap [-h] [-H] [-v] [-p] [-l LOGFILE] ... + + positional arguments: + command QEMU command line to invoke + + optional arguments: + -h, --help show this help message and exit + -H, --hmp Use HMP interface + -v, --verbose Verbose (echo commands sent and received) + -p, --pretty Pretty-print JSON + -l LOGFILE, --logfile LOGFILE + Save log of all QMP messages to PATH + + Usage + ----- + + Prepend "qmp-shell-wrap" to your usual QEMU command line:: + + > qmp-shell-wrap qemu-system-x86_64 -M q35 -m 4096 -display none + Welcome to the QMP low-level shell! + Connected + (QEMU) """ parser =3D common_parser() parser.add_argument('command', nargs=3Dargparse.REMAINDER, diff --git a/python/qemu/qmp/util.py b/python/qemu/qmp/util.py index 47ec39a8b5e..a8229e55245 100644 --- a/python/qemu/qmp/util.py +++ b/python/qemu/qmp/util.py @@ -49,7 +49,7 @@ def get_or_create_event_loop() -> asyncio.AbstractEventLo= op: =20 async def flush(writer: asyncio.StreamWriter) -> None: """ - Utility function to ensure a StreamWriter is *fully* drained. + Utility function to ensure an `asyncio.StreamWriter` is *fully* draine= d. =20 `asyncio.StreamWriter.drain` only promises we will return to below the "high-water mark". This function ensures we flush the entire @@ -89,7 +89,7 @@ def bottom_half(func: T) -> T: =20 These methods do not, in general, have the ability to directly report information to a caller=E2=80=99s context and will usually be - collected as a Task result instead. + collected as an `asyncio.Task` result instead. =20 They must not call upper-half functions directly. """ @@ -105,8 +105,11 @@ def exception_summary(exc: BaseException) -> str: """ Return a summary string of an arbitrary exception. =20 - It will be of the form "ExceptionType: Error Message", if the error + It will be of the form "ExceptionType: Error Message" if the error string is non-empty, and just "ExceptionType" otherwise. + + This code is based on CPython's implementation of + `traceback.TracebackException.format_exception_only`. """ name =3D type(exc).__qualname__ smod =3D type(exc).__module__ --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876654; cv=none; d=zohomail.com; s=zohoarc; b=JTWECv5xgRysc5ssiFUGduElwXPS+oTgsUJOg3GQ3weK/V5ZWB17qh2OlZSR1lf1j2WF3uc/zIggjOOTFVU4kBa+/1EEGNRT43o+ZVA2cfXNHkZ4u/QMATNYwwzZaf9LFtkX3hKdGiH/AkfvR0jgT1IJnCnV3dwl38HGlFC2eWg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876654; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=nO2aYUg1ahQ3Mq+J7zWco6tMP/5HUaKkGg+NPQtmCCc=; b=MtwNsrgi1/uKPOD7886MBkBpOyZc+xBib/COnLa0/BiVhpDJTYSGv3HomuNcCcYfN9ZYSr5DNwYnS6t7vtsRuU7yanXdQk4YXtdhpykAC3lCSlbUVj7h9FUw7NmEafzkRGN0SHIAZUzO2BH9NQ6HXmP3f3Ses1WIis8Ke8MrAFU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175687665446411.4753975520631; Tue, 2 Sep 2025 22:17:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfpA-0008N1-CD; Wed, 03 Sep 2025 01:14:25 -0400 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 1utfn2-0006L0-Ey for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:13 -0400 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 1utfmz-0006i9-85 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:11 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-360-3SoUXclmNNqLCAj2OV1EWw-1; Wed, 03 Sep 2025 01:12:05 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E0B46180048E; Wed, 3 Sep 2025 05:12:04 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CC67719560A2; Wed, 3 Sep 2025 05:12:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876327; 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=nO2aYUg1ahQ3Mq+J7zWco6tMP/5HUaKkGg+NPQtmCCc=; b=Z2Ev30wy4EaQBBCv4+LgtGpUxMkb5DFvT22RDoRBf3JQ6N0oZc46Y+Q4tRciTZpxiCya8X NhQNTm9OWunQn+qc3ZJ2Nd2qPNWQL+T1/tu3sgGMHVI5acnwD4hnY/gbKd1mO2UHkJiSCz vzkE92TaezodCj0Stmh8oOXxaabxKZc= X-MC-Unique: 3SoUXclmNNqLCAj2OV1EWw-1 X-Mimecast-MFC-AGG-ID: 3SoUXclmNNqLCAj2OV1EWw_1756876325 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 14/18] iotests: drop compat for old version context manager Date: Wed, 3 Sep 2025 01:11:20 -0400 Message-ID: <20250903051125.3020805-15-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876656351116600 From: Daniel P. Berrang=C3=A9 Our minimum python is now 3.9, so back compat with prior python versions is no longer required. Signed-off-by: Daniel P. Berrang=C3=A9 Signed-off-by: John Snow --- tests/qemu-iotests/testenv.py | 7 ++----- tests/qemu-iotests/testrunner.py | 9 ++------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py index 6326e46b7b1..29caaa8a349 100644 --- a/tests/qemu-iotests/testenv.py +++ b/tests/qemu-iotests/testenv.py @@ -22,15 +22,12 @@ from pathlib import Path import shutil import collections +import contextlib import random import subprocess import glob from typing import List, Dict, Any, Optional =20 -if sys.version_info >=3D (3, 9): - from contextlib import AbstractContextManager as ContextManager -else: - from typing import ContextManager =20 DEF_GDB_OPTIONS =3D 'localhost:12345' =20 @@ -58,7 +55,7 @@ def get_default_machine(qemu_prog: str) -> str: return default_machine =20 =20 -class TestEnv(ContextManager['TestEnv']): +class TestEnv(contextlib.AbstractContextManager['TestEnv']): """ Manage system environment for running tests =20 diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunn= er.py index 2e236c8fa39..14cc8492f9f 100644 --- a/tests/qemu-iotests/testrunner.py +++ b/tests/qemu-iotests/testrunner.py @@ -30,11 +30,6 @@ from typing import List, Optional, Any, Sequence, Dict from testenv import TestEnv =20 -if sys.version_info >=3D (3, 9): - from contextlib import AbstractContextManager as ContextManager -else: - from typing import ContextManager - =20 def silent_unlink(path: Path) -> None: try: @@ -57,7 +52,7 @@ def file_diff(file1: str, file2: str) -> List[str]: return res =20 =20 -class LastElapsedTime(ContextManager['LastElapsedTime']): +class LastElapsedTime(contextlib.AbstractContextManager['LastElapsedTime']= ): """ Cache for elapsed time for tests, to show it during new test run =20 It is safe to use get() at any time. To use update(), you must either @@ -112,7 +107,7 @@ def __init__(self, status: str, description: str =3D '', self.interrupted =3D interrupted =20 =20 -class TestRunner(ContextManager['TestRunner']): +class TestRunner(contextlib.AbstractContextManager['TestRunner']): shared_self =3D None =20 @staticmethod --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876563; cv=none; d=zohomail.com; s=zohoarc; b=bhWAW44mgm7fz2DjzzHqPBSOvXkvfNUJ4ys5w49zcCChA37QTFipajbrpvf98HJyacwHMjFRiB1pgHBKLuQu24YNDFHZaDqTjzFtxwBsQojHKvNT2peI/RgvXzuAi82UCwFGeYAVUrzfz41ghwatVpt5+AwyBpz7++45cBOvA5g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876563; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/BmZ9w7l2CougITuHQBHRbvcKQikdf1OA1lcFK/juXY=; b=WFAZqJHqizbXOWn+3xTO56ih5Lf0TS9muM7kJ+FuS8bLRG/d+evRLllZS46ZlNXuzlDn9MYhsCZvbyQL+cnJ32BOvixoDM8iE1plJFi3ihzFzYlLhB8kly4uYm2o7iPdH4Uy7sLy4tUj/vlOuHg4V4JYQJJgEEXZ5jytJHisfe0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876563796213.42205882010887; Tue, 2 Sep 2025 22:16:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfpT-0000sC-6C; Wed, 03 Sep 2025 01:14:43 -0400 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 1utfn7-0006N3-T5 for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:19 -0400 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 1utfn4-0006sz-5d for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:16 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-668-2iWvJj1kOXiEUh1eW0uvWw-1; Wed, 03 Sep 2025 01:12:08 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E6D081800365; Wed, 3 Sep 2025 05:12:07 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5E3E619560A2; Wed, 3 Sep 2025 05:12:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876332; 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=/BmZ9w7l2CougITuHQBHRbvcKQikdf1OA1lcFK/juXY=; b=OfNMV6x9mSt50gdjN5c3uZ9PxPekFsY3o9vHGUf71sm7WETpSlQajIpCTiZaPLh2qSlBGK BCngpkZZbpNrpBOdk+OffPl+EuPL5Fyw0E5136QBEBhwSPDwLD/8mzQ+UqptfkOm4DhJaN Z7b7pcQ6ZviAr/x0Ylcdr5w/PItN9js= X-MC-Unique: 2iWvJj1kOXiEUh1eW0uvWw-1 X-Mimecast-MFC-AGG-ID: 2iWvJj1kOXiEUh1eW0uvWw_1756876328 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 15/18] python: ensure QEMUQtestProtocol closes its socket Date: Wed, 3 Sep 2025 01:11:21 -0400 Message-ID: <20250903051125.3020805-16-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876569257116600 From: Daniel P. Berrang=C3=A9 While QEMUQtestMachine closes the socket that was passed to QEMUQtestProtocol, the python resource leak manager still believes that the copy QEMUQtestProtocol holds is open. We must explicitly call close to avoid this leak warnnig. Signed-off-by: Daniel P. Berrang=C3=A9 Signed-off-by: John Snow --- python/qemu/machine/qtest.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/qemu/machine/qtest.py b/python/qemu/machine/qtest.py index 4f5ede85b23..781f674ffaf 100644 --- a/python/qemu/machine/qtest.py +++ b/python/qemu/machine/qtest.py @@ -177,6 +177,8 @@ def _post_shutdown(self) -> None: self._qtest_sock_pair[0].close() self._qtest_sock_pair[1].close() self._qtest_sock_pair =3D None + if self._qtest is not None: + self._qtest.close() super()._post_shutdown() =20 def qtest(self, cmd: str) -> str: --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876665; cv=none; d=zohomail.com; s=zohoarc; b=egc1c/x8CsaIo00BdcMK4a4q9lZVBbra369fUgFOvS4LSsd1Ddjh9XAlXZHru42cyGnTAeeynh2SfX7C4E8gQ+Bf/OuSPO7Wk2W2hbXqKOdfj/BkCNLS0c5MiO1TfznoD97ukHz5GGtfasFULJQWloPANpRA+Ru5syoiNuL4r+s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876665; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=redY3J6Go7FDZCUZVMBmRGiuKOFKplF9JXDgVj4SBW8=; b=Le7iz6BUSrBNN+9U9Rr+EgpHAOZ4EiT2W190uAGUe1G9t9E88i6zCELqGj15naI+2h4RuyHf27raK0IS8aPcJj2+ZPruIqFquPqAvirrlwKoPGmpuw0vxa6FfqmuCmVTfRjPkZZHMOXUMZSTAiuxhzBZxJSeo5FW5nyFrOUIMCE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175687666513099.92360698161121; Tue, 2 Sep 2025 22:17:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfpX-0001BY-0B; Wed, 03 Sep 2025 01:14:47 -0400 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 1utfn9-0006NJ-DY for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:19 -0400 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 1utfn4-0006tg-7J for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:18 -0400 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-488-J6J_tIc5P7yA0Quu2qPEOg-1; Wed, 03 Sep 2025 01:12:11 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 C156219560B2; Wed, 3 Sep 2025 05:12:10 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3EF1019560A2; Wed, 3 Sep 2025 05:12:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876333; 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=redY3J6Go7FDZCUZVMBmRGiuKOFKplF9JXDgVj4SBW8=; b=bFjc/RltS7BFa3XapqfejNhD08gO5KtvgCn3tYz93z8PQc5UYvq76A9FZo+vJ2GE4QvKyc cFdxBLjQNy2psDeSvSFgmvalQhNdu8lopf/HGN0zX2XPQC5FbKS3IvXbnXwzOk4QeTGrnY 3eRSNRj1nS7lks17lpv82W26eFjP+io= X-MC-Unique: J6J_tIc5P7yA0Quu2qPEOg-1 X-Mimecast-MFC-AGG-ID: J6J_tIc5P7yA0Quu2qPEOg_1756876330 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 16/18] iotests/147: ensure temporary sockets are closed before exiting Date: Wed, 3 Sep 2025 01:11:22 -0400 Message-ID: <20250903051125.3020805-17-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876666375116600 From: Daniel P. Berrang=C3=A9 This avoids the python resource leak detector from issuing warnings in the iotests. Signed-off-by: Daniel P. Berrang=C3=A9 Signed-off-by: John Snow --- tests/qemu-iotests/147 | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 index 6d6f077a14d..3e14bd389a4 100755 --- a/tests/qemu-iotests/147 +++ b/tests/qemu-iotests/147 @@ -277,6 +277,7 @@ class BuiltinNBD(NBDBlockdevAddBase): } } self.client_test(filename, flatten_sock_addr(address), 'nbd-export= ') =20 + sockfd.close() self._server_down() =20 =20 --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876673; cv=none; d=zohomail.com; s=zohoarc; b=dxbSfw9z63XvH7E/EX0w4NEh/Gh3Sy6bDlAYRIk4NZoLR6tChpraWmiwlYbBUyQ1Rcv5vV/7SJvMRV7vX4O2ZSXpTYPnYnXAp6HJVIrKogdSLgujULf1T/AOUFV+xJ5mUNEIgkrD7reqP7bHBpGvuGvDtLf1mwueDb6S3Qyvs7s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876673; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=c/lFu6o8E1HCKXvUoJO2x7slIVPWYpyPrHnksOMI3CY=; b=aDTNvsbegBU75NX9R+mAzKxSeZmlEzla3oeyBnJtb8IMoOPF7yXM3g7vjnsM2xRclyt9HP66YfpbWDlwgvEc785FMglFBPdecWxptf7dyY1cGd2MpjOlNlmD+o6U0otkWr027QemnmdN0W4szbP0djqf4FOH5LB8Uy1Ah/iiUQs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876673938574.1984163674308; Tue, 2 Sep 2025 22:17:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfpR-0000Yn-0N; Wed, 03 Sep 2025 01:14:41 -0400 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 1utfnB-0006Ok-Fl for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:21 -0400 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 1utfn9-00074i-6y for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:21 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-595-TglZedj8NvCPIFRjtNReIw-1; Wed, 03 Sep 2025 01:12:14 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 01583180034D; Wed, 3 Sep 2025 05:12:14 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8868219560A2; Wed, 3 Sep 2025 05:12:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876338; 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=c/lFu6o8E1HCKXvUoJO2x7slIVPWYpyPrHnksOMI3CY=; b=Oc4TPeAtS51G/Z8vrQGgjyJJjd54DWIkhq2oD783/xVzn++zxZMQT7a5g/iC3tfhf3IgSr 1vr+2tw+Bz2U5SYqgXOuVCY4Ju+OOrfemmC02g4WuNdkaeHr86WBYvR+apOtuKPWDMu/VC tvxQNE29REWC7QR/p2bdaLExG8VaK1k= X-MC-Unique: TglZedj8NvCPIFRjtNReIw-1 X-Mimecast-MFC-AGG-ID: TglZedj8NvCPIFRjtNReIw_1756876334 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 17/18] iotests/151: ensure subprocesses are cleaned up Date: Wed, 3 Sep 2025 01:11:23 -0400 Message-ID: <20250903051125.3020805-18-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876674513116600 From: Daniel P. Berrang=C3=A9 The iotest 151 creates a bunch of subprocesses, with their stdout connected to a pipe but never reads any data from them and does not gurantee the processes are killed on cleanup. This triggers resource leak warnings from python when the subprocess.Popen object is garbage collected. Signed-off-by: Daniel P. Berrang=C3=A9 Signed-off-by: John Snow --- tests/qemu-iotests/151 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151 index f2ff9c5dac2..06ee3585db9 100755 --- a/tests/qemu-iotests/151 +++ b/tests/qemu-iotests/151 @@ -263,6 +263,11 @@ class TestThrottledWithNbdExportBase(iotests.QMPTestCa= se): break except subprocess.TimeoutExpired: self.vm.qtest(f'clock_step {1 * 1000 * 1000 * 1000= }') + try: + p.kill() + p.stdout.close() + except: + pass except IndexError: pass =20 --=20 2.50.1 From nobody Mon Sep 8 09:47:37 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1756876489; cv=none; d=zohomail.com; s=zohoarc; b=W8kjQU/JcS33rauyWcmiAsiqlRqdf8UmAGOajT3DCc64q//tWsgYan/XvewbE/1A0PUaVjoyJn41a94Cm7/A/f78BZimmBe5WttPSz4ZQM3VpUMZH8m/fdE99FR6/oQ0FEzCkK+84Nsd/SmOn7T4Nfoy+/9B91XNdsPl1RT1mRw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756876489; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=A4xBFXb45hM+ZJ7Arv4NuY5r0toY1PnfWxR1gk8ah2U=; b=YJJKErlzTGSVxqjDK2b1I2twCyNA3xksUPJmjPaI3PINqdZIbUivv2RxwAY6YB9Bz2SHYfaYbCaoRCqBHrN1oBlQ2SjBJ51TMhWbSd84LJuuoVBqL470cFyN1n11eWS3tCp09quXZP9gNdXj2sl4gLQzmgJMJMhUWHzWuF0wGDs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756876489352422.70061768009964; Tue, 2 Sep 2025 22:14:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1utfpU-0000zP-L8; Wed, 03 Sep 2025 01:14:45 -0400 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 1utfnF-0006SA-SZ for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:29 -0400 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 1utfnD-000789-Mi for qemu-devel@nongnu.org; Wed, 03 Sep 2025 01:12:25 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-139-KH8MpBioO6GDGy71av25gw-1; Wed, 03 Sep 2025 01:12:19 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B593E18004D4; Wed, 3 Sep 2025 05:12:18 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.53]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 73E2C19560A2; Wed, 3 Sep 2025 05:12:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756876342; 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=A4xBFXb45hM+ZJ7Arv4NuY5r0toY1PnfWxR1gk8ah2U=; b=E8fyL6VQzOMDIEEynkmVBBov11E7CWnFWEGTB2X6hu+l8c5FFIJAIfF9mkr9B2vKIzwXuB um6CGrhZ3R0Uw6MjhnhqETFHqEcyJGpZe+On1ayDE3gj8+rAQLnuefsX2+ziAuyMuhP5ah d0Y/HSgzYQGSfMdNEYn0UQB/R5kO6aQ= X-MC-Unique: KH8MpBioO6GDGy71av25gw-1 X-Mimecast-MFC-AGG-ID: KH8MpBioO6GDGy71av25gw_1756876338 From: John Snow To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, Cleber Rosa , =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Kevin Wolf Subject: [PATCH v2 18/18] iotests/check: always enable all python warnings Date: Wed, 3 Sep 2025 01:11:24 -0400 Message-ID: <20250903051125.3020805-19-jsnow@redhat.com> In-Reply-To: <20250903051125.3020805-1-jsnow@redhat.com> References: <20250903051125.3020805-1-jsnow@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; 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: -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, 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1756876490262116600 From: Daniel P. Berrang=C3=A9 Of most importance is that this gives us a heads-up if anything we rely on has been deprecated. The default python behaviour only emits a warning if triggered from __main__ which is very limited. Setting the env variable further ensures that any python child processes will also display warnings. Signed-off-by: Daniel P. Berrang=C3=A9 Signed-off-by: John Snow --- tests/qemu-iotests/check | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check index 545f9ec7bdd..d9b7c1d5989 100755 --- a/tests/qemu-iotests/check +++ b/tests/qemu-iotests/check @@ -21,6 +21,7 @@ import sys import argparse import shutil from pathlib import Path +import warnings =20 from findtests import TestFinder from testenv import TestEnv @@ -137,6 +138,9 @@ def make_argparser() -> argparse.ArgumentParser: =20 =20 if __name__ =3D=3D '__main__': + warnings.simplefilter("default") + os.environ["PYTHONWARNINGS"] =3D "default" + args =3D make_argparser().parse_args() =20 env =3D TestEnv(source_dir=3Dargs.source_dir, --=20 2.50.1