From nobody Wed Sep 10 01:54:45 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=1757358328; cv=none; d=zohomail.com; s=zohoarc; b=gzbPJvLL4X8aMcZc0YPvcPJs2jyfTTMjSaU5l2HLnXZDVcozHN5rVza5Kp3iK5+Q13uY9aekJVKGoRi0squJgUVnZJj9x73DUtPpF7wV8ZREtFJxasYCJJ8Jtr48cqSz+WiVKkfs/CscsUChIvwGELe/uHJPAbfNZD1+J/hS3g4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358328; 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=L/P1+4BHrRd1Cp97yvkaOCR+Jmni8jiTf79S1Ab1IDs=; b=YaP82mUQl/zwyM3nUisQtEwrfBhgASv5SEUQiMulqFJ2kb2F76rTJBIDVO2ighAnfeQddUP4uEMlWSpk400kNcd2abl5D0CvNdGa+jiZCw4I8vakdh3l7G8hqxTZqSJ2e9WytW5u9WVnE5zCZ4bAqbXGOnZlXVhxh2e6jsBgN5A= 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 1757358328869437.97702897304873; Mon, 8 Sep 2025 12:05:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvh9i-0006A8-Kc; Mon, 08 Sep 2025 15:03:58 -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 1uvh9b-00068y-13 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:03: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 1uvh9N-0007rA-GW for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:03:50 -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-230-gdh93M2aMEmsWW7KKfJ6qQ-1; Mon, 08 Sep 2025 15:03:27 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 8F71E1800296; Mon, 8 Sep 2025 19:03:26 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id DEE151955F24; Mon, 8 Sep 2025 19:03:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358211; 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=L/P1+4BHrRd1Cp97yvkaOCR+Jmni8jiTf79S1Ab1IDs=; b=iAi6W26Wkuc0WpdNiCzTYYcJn6thzrls6yNDi8QB55JbMhJGLm8hrC8lRSqPCpD7eCh5KY q0dpRCOORgt1Hjtv3d4ARxQ06/W4G4GuqRgtycDPrORAJIsALBk7/7PJad4Va5tqORt0bE 7oVppGtN/Z4uOLLdQydDtnZLEyc2EWQ= X-MC-Unique: gdh93M2aMEmsWW7KKfJ6qQ-1 X-Mimecast-MFC-AGG-ID: gdh93M2aMEmsWW7KKfJ6qQ_1757358206 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 01/19] python: backport 'Change error classes to have better repr methods' Date: Mon, 8 Sep 2025 15:03:00 -0400 Message-ID: <20250908190318.3331728-2-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358330766116600 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 python-qemu-qmp@afdb7893f3b34212da4259b7202973f9a= 8cb85b3 Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358883; cv=none; d=zohomail.com; s=zohoarc; b=GDb7j57Y9j7n/uEhWhtJpnQ7abqMqQ0F/i+cByBvpCAKTHNBj6UOwtWrMWAqfg6fQKpxgQszBI+eE9+VjHfSL3gSsIklec6VRqBGo9kl56y/fDIEE2lfRob/vy+oHj3fKGXt65HO8iobdBeL5bar64uDLKOfErTYgaM+XkQ/vdA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358883; 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=sg3+K42TjHTCHBz/doPg1ENvH2yOKzAmlCKgdHLoqQs=; b=mvfOSvj3RAM9i0UDxUQQFfAXXuYxPnhCNEHSGZ+YVwCVEtVogpDC3A3+TDEC7KhuTk0GsJI9BPb15MKfNhdJoMGk33M95XvrxRlDrIArIv25YvlnIMMKdKKHvxMdaEXORvhWfk3VXn62LvAfuJ84+L59AD9ROLP0xQSkilRUWP4= 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 1757358883970471.24424280485425; Mon, 8 Sep 2025 12:14:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvh9m-0006Af-VO; Mon, 08 Sep 2025 15:04:05 -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 1uvh9e-00069S-Bt for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:03:54 -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 1uvh9N-0007rM-Re for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:03:53 -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-114-K_coBnfdNpGnYCnhvK-gPA-1; Mon, 08 Sep 2025 15:03:30 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 A643519560B7; Mon, 8 Sep 2025 19:03:29 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2A54A19540EE; Mon, 8 Sep 2025 19:03:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358212; 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=sg3+K42TjHTCHBz/doPg1ENvH2yOKzAmlCKgdHLoqQs=; b=IXoB3j/UsPoSvtA5Z0ueTWbkwW9X9m6sYsiq0IFPfk1e9EOCmXt+kvc9gjT40YKyi19vsI UXKmLmTgHoYfJme7AUhKDwidjs1Ye6lbvboWgthGOISnEWvgoqzjx37ear8jnZSwjEt8r0 kgquZ9uOj6GKQ11MIxdiEfF63Yd912k= X-MC-Unique: K_coBnfdNpGnYCnhvK-gPA-1 X-Mimecast-MFC-AGG-ID: K_coBnfdNpGnYCnhvK-gPA_1757358209 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 02/19] python: backport 'EventListener: add __repr__ method' Date: Mon, 8 Sep 2025 15:03:01 -0400 Message-ID: <20250908190318.3331728-3-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358886025116600 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 python-qemu-qmp@8a6f2e136dae395fec8aa5fd77487cfe1= 2d9e05e Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358330; cv=none; d=zohomail.com; s=zohoarc; b=FCL617vuSspT4aWAiPKZjNqv0XoEX4CMUbWHlLhfda0fk+DLojPmKlSlB4Eyo2Ez2MXY4yGmsKlLKWKcucSPLDjfZU1GyLQ9imKt2IBC8CAkrhjT3dXlpg/mnqEQ+ixRPcQvhI6JuwSFgfcXyAfJqhPHcrgew2wWnuVYHh8Z9rs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358330; 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=mqFYKPdRljx5p1+IqtPOY4ciCtGUhk8HuJXyltDHZGY=; b=P+d2WXVF/qE2wjGnMMKCsspyFzS/FOxkQf8w/lFs2XtptILUJOZ4xdoT/OhYoxcHa9OA/vnEHe381ioTifrN/EeHA8y7Q3Kf9h6b6bfIeVV2PXvs4ccYPqL3zGDO9+PHjV8IYZ7gi5ntWa5kXvNfR2qZM0V1ixR+6l7lboj2D9o= 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 1757358330361661.5297897389044; Mon, 8 Sep 2025 12:05:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvh9p-0006Ai-0b; Mon, 08 Sep 2025 15:04: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 1uvh9e-00069s-VE for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:03: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 1uvh9P-0007s2-OR for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:03:54 -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-637-gDdC7NRdMMSq6Xh2Q6_NxQ-1; Mon, 08 Sep 2025 15:03:33 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 E3F6C1955F28; Mon, 8 Sep 2025 19:03:32 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5F5821955F24; Mon, 8 Sep 2025 19:03:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358215; 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=mqFYKPdRljx5p1+IqtPOY4ciCtGUhk8HuJXyltDHZGY=; b=ACaHVsRztQKfx7PEQ9Pp/IV108olV19Xe3HW9Ot58l1UmrMHOVry/M7/uuHRyrXKAuRi5L iox8mfdtZwEigqHpRQZfcw4G9ENHBIAORj9eK0i2D62qztzCQMWY+gQ29OZTz37OLRF/dA hFOhItHyB8rs7iOUqhrpBUPQsDXrp7I= X-MC-Unique: gDdC7NRdMMSq6Xh2Q6_NxQ-1 X-Mimecast-MFC-AGG-ID: gDdC7NRdMMSq6Xh2Q6_NxQ_1757358213 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa , Jag Raman Subject: [PATCH v3 03/19] python: backport 'kick event queue on legacy event_pull()' Date: Mon, 8 Sep 2025 15:03:02 -0400 Message-ID: <20250908190318.3331728-4-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358331973116600 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 python-qemu-qmp@0443582d16cf9efd52b2c41a7b5be7af4= 2c856cd Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358330; cv=none; d=zohomail.com; s=zohoarc; b=bdv8qp8xcBybk/L0jobIIkLfHXDy4CDqIK1hD1IWxZd2xiuiIUZcMhCrfV/3Pl1PN1NT2KZTwJ849FTtrJGD317Y6LlB0jdMM7g+cGI10SWI5oehZZFsJAvODLziX+LK4iIpwhf9XMQqq4Jm59m4k7dzcQGkIoktmehtibgVkVQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358330; 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=9UOH1v7iDb17AOjSKYGHnGg8Q8WrDG6XsglpGgVGVYA=; b=Ay0uJLHYUP6i3uexsNmHBn5uxyAwNvV1/F12KoOeYecgWzPoSuDHHgMuiyWWZcGaE0Bvu4PeL2afI2Tmu9gdHZilGLfIXYR8DpLqS/jL+Tdr9DykS1WGcOmednwX6a2OntagWuyEHo32gI+IZr0k8rOdrAA2TbCW/go4+IMOUyk= 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 1757358330726983.6053740282192; Mon, 8 Sep 2025 12:05:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvh9u-0006JF-Be; Mon, 08 Sep 2025 15:04: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 1uvh9o-0006En-OQ for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:04 -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 1uvh9T-0007st-7f for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:04 -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-685-gJMb8T1nNg65iAXLMdRBEg-1; Mon, 08 Sep 2025 15:03:37 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 2C71719560BA; Mon, 8 Sep 2025 19:03:36 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 853961955F24; Mon, 8 Sep 2025 19:03:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358218; 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=9UOH1v7iDb17AOjSKYGHnGg8Q8WrDG6XsglpGgVGVYA=; b=iLn6UXWdKO3KvrHgqgB2ydASd2i6qByForLiLfuF/fEbiCiW9oY1epE0cj7Sur/K8dMSjQ wMOCq2T96TdGRaCvQFXOqHt7eGBS5QLcEfcoM7HPWz+xHvRcx/F9X0ZFTFIZ8vt7f+46pg l0bcqec5gOEzyDQTlRx5xjfyjSXXFB4= X-MC-Unique: gJMb8T1nNg65iAXLMdRBEg-1 X-Mimecast-MFC-AGG-ID: gJMb8T1nNg65iAXLMdRBEg_1757358216 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 04/19] python: backport 'protocol: adjust logging name when changing client name' Date: Mon, 8 Sep 2025 15:03:03 -0400 Message-ID: <20250908190318.3331728-5-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_PASS=-0.001, T_SPF_HELO_TEMPERROR=0.01 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: 1757358333136124100 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 python-qemu-qmp@e10b73c633ce138ba30bc8beccd2ab319= 89eaf3d Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358331; cv=none; d=zohomail.com; s=zohoarc; b=HRnCJIU4c/FgQrPqBeIjtxj1GTsoCka6dlDyyPk/BvUjiJs4jgDLUv75GKTweHgcU6IWt6+4SfHla0+6ETNuUKxUCGYix1zGvfiYP+3EE6OgEuV9Cs0qHRCtxlhmYAbFMY22GDLvzGwEJ5FDdnsQiHHWPgo9Q5Uw2Odl4pW0Puc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358331; 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=B3q1PizBcwe79dj3apfnbfegX+x5eBK+qcS0PEyAfPA=; b=MCuK6D3CsVUc6BjgvZLlNMrry8DCKqXTKchOAvo/OY4k+9iF66H9Xm7xEZjuDn15Bsnl4yvBYw5yWBQuuH4T9+5BYWYeKj1XcYuMReG4uLBuStxNWgPpyHP+KahHHi0GjeeyCJ5dSLaFRjjdgzz8qDzQosjmmTpbqUOsS25aolw= 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 1757358331156467.99183975723815; Mon, 8 Sep 2025 12:05:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvh9z-0006Md-FO; Mon, 08 Sep 2025 15:04:15 -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 1uvh9x-0006Ld-CE for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:13 -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 1uvh9V-0007tI-P5 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:12 -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-163-dsoRXy2_P8ChSgyg9fsK3g-1; Mon, 08 Sep 2025 15:03:39 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 F0E2D19560BA; Mon, 8 Sep 2025 19:03:38 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8E6721955F24; Mon, 8 Sep 2025 19:03:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358221; 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=B3q1PizBcwe79dj3apfnbfegX+x5eBK+qcS0PEyAfPA=; b=heZnRtclxmhY7vEktGigEgRkbqlV2rYJbwimMxkf6S45XAVt5Xe0nsqZ0sdoxl+MPDPARe zzR4K1GJ9zMH3a0mxggGVMjPHS9OAs+O+QD0fg1b8APgml3E/P092c6tDkrFr0qd3wuqRk sBkFJum1xF/l35AdE8+9Nbm+fXNUjqM= X-MC-Unique: dsoRXy2_P8ChSgyg9fsK3g-1 X-Mimecast-MFC-AGG-ID: dsoRXy2_P8ChSgyg9fsK3g_1757358219 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 05/19] python: backport 'drop Python3.6 workarounds' Date: Mon, 8 Sep 2025 15:03:04 -0400 Message-ID: <20250908190318.3331728-6-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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, 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358332207116600 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 python-qemu-qmp@3e8e34e594cfc6b707e6f67959166acde= 4b421b8 Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- python/qemu/qmp/protocol.py | 13 ++--- python/qemu/qmp/qmp_tui.py | 8 +-- python/qemu/qmp/util.py | 107 ++---------------------------------- python/tests/protocol.py | 8 +-- 4 files changed, 17 insertions(+), 119 deletions(-) diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index ec4762c567b..208bdec5c89 100644 --- a/python/qemu/qmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -36,13 +36,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 @@ -682,8 +679,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 +705,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 +841,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 Wed Sep 10 01:54:45 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=1757358658; cv=none; d=zohomail.com; s=zohoarc; b=g+MfRbQ4etOjH817wFnPBndLhgxKnqW6eWovILqs3sg/FIzAVfJ5u1904NbEqXLEnNdvF91ak/ZIz/T6nkWnD0Aip67yx0Z7HZ9e0ay7+jYFi8Y0yhOUFW/jCOGBsKK0YWU+9xkMWeMno9n0HDy3aUjZy3q4Mi02hHWjqixq4Xg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358658; 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=4cXiUx1NSS253XfDgfMgVAMOW1SkWQ61spfOO0h1sRQ=; b=gVoFac7B65DckjPSKM3wFdHcr0B6zcfcyQRKZg1U6IC6Pm41Oyq5Axpvkk6F4R65eflaaErxanU/w6YaaZi8g+8ecdBG3Lczw+wPCVfY5ird9vGgNsl9VY3EugX7FRKsb71hrmyXdDXFIia4ftWGDXHonZ1mhQoomJ69j6iFrWs= 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 1757358658707447.6619953036293; Mon, 8 Sep 2025 12:10:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvh9v-0006Ky-Jd; Mon, 08 Sep 2025 15:04:11 -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 1uvh9u-0006Gx-65 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:10 -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 1uvh9Y-0007u1-TK for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:08 -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-635-w2TTEH5kOPWzAWOJuHI_7w-1; Mon, 08 Sep 2025 15:03:42 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 E82D11800294; Mon, 8 Sep 2025 19:03:41 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 70AC31955F24; Mon, 8 Sep 2025 19:03:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358224; 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=4cXiUx1NSS253XfDgfMgVAMOW1SkWQ61spfOO0h1sRQ=; b=VL8O70oj6mEsk8609XTr66L31L1sj31mvYV0e7vacdtcvMrmcpIi0Y/WBS5Xs0nevrjYnZ wrhXe60HP9KukN1HI8g9HceMPfxngHB+WQxr8N+zfL5/Wb6Ve8A19K3EWJF1KfEaW+13kE Ja+2NPThxKJ7IqUCxKIKmK36NIgzDAk= X-MC-Unique: w2TTEH5kOPWzAWOJuHI_7w-1 X-Mimecast-MFC-AGG-ID: w2TTEH5kOPWzAWOJuHI_7w_1757358222 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 06/19] python: backport 'Use @asynciocontextmanager' Date: Mon, 8 Sep 2025 15:03:05 -0400 Message-ID: <20250908190318.3331728-7-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358660498124100 This removes a non-idiomatic use of a "coroutine callback" in favor of something a bit more standardized. Signed-off-by: John Snow cherry picked from commit python-qemu-qmp@commit 97f7ffa3be17a50544b52767d1= 4b6fd478c07b9e Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- python/qemu/qmp/protocol.py | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/python/qemu/qmp/protocol.py b/python/qemu/qmp/protocol.py index 208bdec5c89..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, @@ -337,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 @@ -362,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 @@ -392,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 @@ -418,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 @@ -435,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()) --=20 2.50.1 From nobody Wed Sep 10 01:54:45 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=1757358514; cv=none; d=zohomail.com; s=zohoarc; b=YoWfy3Nc4gGz37rq3tbrZ/zX6CsDIQw8brwMXbrJM5x8vYNMwk5RIaasSEEKV0wDLoNboweKKOr3Yb1vFfOAqFsYbopApW0p1gbg8wY6aWdDrogjxLQmQKcJ9/4cByv0SV8VJBmAGv3zjbz7RPawPN/0BO5buW9wiSYBHJh5fhA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358514; 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=xH1L6KX3xDUHN5YbMX30PuPYCA/G+bTmMn+xTkM7Iss=; b=I7tnGRoyAsH+1mqU9CUpvraQPegqY6Ba8jeylfQ7sn4YxZ67svy3McBQGji/IGcbC4UjYKTHVs13Y7MFAcIg/G0wYnYIheloPFQ9Hl9yeF1mJ/GMhRaatL29+VdtOl+9BN3MagwFBywUSP9TF/TPtFRLNkAXz4289aPEyLbAfIw= 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 1757358514147370.2249003758292; Mon, 8 Sep 2025 12:08:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAB-0006Xb-GR; Mon, 08 Sep 2025 15:04:27 -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 1uvhA1-0006NB-Gu for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:17 -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 1uvh9d-0007uy-Il for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:16 -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-214-PrBpw6miMR-9p5PcbFgVzQ-1; Mon, 08 Sep 2025 15:03:46 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 4FCD219560AA; Mon, 8 Sep 2025 19:03:45 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 831881955F24; Mon, 8 Sep 2025 19:03:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358230; 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=xH1L6KX3xDUHN5YbMX30PuPYCA/G+bTmMn+xTkM7Iss=; b=Rtcdmq+FY/CCdg971kW7R2PJh4m93xTNq+5ZNt2yKi7pvQPBgTvLMKGmHmALQ79pjFFpOa +n43QXZ4yLZKvVV+KQl5h/hrGw0TpGtLv/ZaKK75xHNUYqOpB6TF4RCCCKFGljXOUNDtEy vxnAw5o/3AJRAhMbaBkgrQ6AldHUZxc= X-MC-Unique: PrBpw6miMR-9p5PcbFgVzQ-1 X-Mimecast-MFC-AGG-ID: PrBpw6miMR-9p5PcbFgVzQ_1757358225 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 07/19] python: backport 'qmp-shell: add common_parser()' Date: Mon, 8 Sep 2025 15:03:06 -0400 Message-ID: <20250908190318.3331728-8-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, T_SPF_TEMPERROR=0.01 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: 1757358516323116600 Signed-off-by: John Snow cherry picked from commit python-qemu-qmp@20a88c2471f37d10520b2409046d59e1d= 0f1e905 Signed-off-by: John Snow Signed-off-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358423; cv=none; d=zohomail.com; s=zohoarc; b=kjL5oq/tJYM15Y1EmfZS+O7lj9EFxQBwC64bmZjVDpSZUdOxRMX59zlyaxzMnoCmtQhT4L4oBZDGa9FnmZzQHHKCi2YSKb9DFzOyE5Kjkj4HbKwPw4TB6sx7na7WlUQr1T2lB9wkbv8u7eUD0zk5KclKKg9xXCHbCVUFclbEE/Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358423; 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=pAKQ4lWQcb8M2/ELQm3nYTRu22pkXYPl3VSBrus9tOc=; b=Cg5dgPMbXCQory5tFWgBJNGTEvgi9iJP5nKHM5w2d8J1yLAkQOaYg85OTrO1RaBqGMTCp2x2G0mh48C2cFctKSiyc9ZKMciqI3TQ5VR+NoMgFAPFyw/MB+lS2RjFLvHQz3hRprOIjTah/ZOWwHirXiy3QPxdizT+ipHlkn24Xwc= 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 1757358423258892.2007359209583; Mon, 8 Sep 2025 12:07:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAB-0006Xa-H1; Mon, 08 Sep 2025 15:04:27 -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 1uvhA2-0006PH-3a for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:18 -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 1uvh9f-0007vP-Mk for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:17 -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-413-UzjCwTSwNsO15WSZP3ptnw-1; Mon, 08 Sep 2025 15:03:50 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 991CB1955D61; Mon, 8 Sep 2025 19:03:49 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E08E51955F24; Mon, 8 Sep 2025 19:03:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358233; 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=pAKQ4lWQcb8M2/ELQm3nYTRu22pkXYPl3VSBrus9tOc=; b=TJFjppvETcECYivIvpFYScRz+1zhiPy1Tcvoqu/TGFmn2ctrW92W26PN/Ei0RXs0OW0sHT DKcth5junON4bDd3qmfOXwkKvq7lqfJXODKoTHRyuJR8UqxwiFqkaExxF6GZZVUDDptFet U61e1o7Q9ha5Cjx8WgL4REsKWcbKngE= X-MC-Unique: UzjCwTSwNsO15WSZP3ptnw-1 X-Mimecast-MFC-AGG-ID: UzjCwTSwNsO15WSZP3ptnw_1757358229 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa , Adam Dorsey , Adam Dorsey Subject: [PATCH v3 08/19] python: backport 'feat: allow setting read buffer limit' Date: Mon, 8 Sep 2025 15:03:07 -0400 Message-ID: <20250908190318.3331728-9-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1757358426350124100 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 python-qemu-qmp@9ba6a698344eb3b570fa4864e906c5404= 2824cd6 cherry picked from commit python-qemu-qmp@e4d0d3f835d82283ee0e48438d1b154e1= 8303491 [Squashed in linter fixups. --js] Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358572; cv=none; d=zohomail.com; s=zohoarc; b=IJSPchArzizG2A/XblXGHkFDgAZ+vtMRLODZqVOFiAZSydhYyQwCB0bSwrww1UfgqZSFWkZBCDcLlOEU/X/gYOowRYveVWdp8uL+n0W6aea8J37L9D7LFWI7rg85d7FSP+5aEuSsKPE1kpYEdoPus6jY16EE1H89Ad95sdg1uow= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358572; 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=DAZWkpMGri2jVLw8LWdG5ostNV1qPOkgRO+9V3g8jI0=; b=IuE0l6zl4EnWy4JVOKcDiSTwZy7vQMlrgzmSYVbMk2n7HoTExh+kr7R6clrX3JL1AYO8CbpMMvYk1bHqy+VQVYCtQDM3Bqc/1yHxJLmCohzPX3l+WWSoAzGgbHuutolO8G4WsOYMmG+g5nyJ5Cai2cVuU1qFlvtV5JSoNzFYaDI= 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 1757358572852616.0406972800444; Mon, 8 Sep 2025 12:09:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhA6-0006TO-Lr; Mon, 08 Sep 2025 15:04: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 1uvhA1-0006NV-1Z for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:18 -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 1uvh9k-0007vn-N2 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04: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-327-10hMYRdIMhyJu5wNuZ0kbA-1; Mon, 08 Sep 2025 15:03:53 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 36BFD180057F; Mon, 8 Sep 2025 19:03:52 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3403A1955F24; Mon, 8 Sep 2025 19:03:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358236; 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=DAZWkpMGri2jVLw8LWdG5ostNV1qPOkgRO+9V3g8jI0=; b=E+FQn33qyxMTvE0KWXu+syE3ie9VXC3ZP2bVT82j2+WVx1B/X0BbzvKyGi9TOkB1K+ZBjZ zuQsb2RqX2QijlV3+MSQEsgIvHkw6R8Y328jbSheaoGk7QprijBstZh9dVMPDDg54pQIXq y27Z4bY3nr6VUb9wiu26x97tdFkIfw4= X-MC-Unique: 10hMYRdIMhyJu5wNuZ0kbA-1 X-Mimecast-MFC-AGG-ID: 10hMYRdIMhyJu5wNuZ0kbA_1757358232 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 09/19] python: backport 'make require() preserve async-ness' Date: Mon, 8 Sep 2025 15:03:08 -0400 Message-ID: <20250908190318.3331728-10-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358575511124100 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 python-qemu-qmp@40aa9699d619849f528032aa456dd061a= 4afa957 Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358333; cv=none; d=zohomail.com; s=zohoarc; b=nbGEfobE6hJwjGGjdSxNO7WpS9DyYj0GICU1pr5ZJFog1V/406+1El0C51r5O7rSK34roogQqyQKxHucL67ZLz8fvq7+/3Jy17yECMadEUqeyfvB8wEkr7Yqjz80NjrHZJoYdasd8DqxMPGOBjY0JP4QOSwjJLC4NFxHxU4wsE4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358333; 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=5BcJeth7DGE5kYRd/Wi2LJ1x8MM9R8VOptsN8riPr8g=; b=hkWkN8J4+KkZPeiJrIwcoA2EuWCtTsD4dy9dg+xPP1OpzO5Z/+7TfBJaldAzcgoGCWj0Ya9t8+nnMQYscacgc5/YzCDejA+8JKE4iEwd+D4ftJPfjbbdDF6+qrBz4U1pLDvcMrf7H96sGHXaoNG8GpLfhKtPdhyeHQRXcfB6EcU= 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 1757358333526440.21486974066613; Mon, 8 Sep 2025 12:05:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhA8-0006X8-K3; Mon, 08 Sep 2025 15:04:26 -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 1uvhA5-0006Qy-0E for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:21 -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 1uvh9n-0007wb-00 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:19 -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-620-xFnlOB7ENlibYFWO5GkFOQ-1; Mon, 08 Sep 2025 15:03:55 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 CEA7D1955F45; Mon, 8 Sep 2025 19:03:54 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EEDFE1955F24; Mon, 8 Sep 2025 19:03:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358239; 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=5BcJeth7DGE5kYRd/Wi2LJ1x8MM9R8VOptsN8riPr8g=; b=HVaQ7tTFYFchwuhCXshfgJBVgyOdUBg7SsrOzILfXL7U1ziYFVihI+HWKTPcyHPswBPx9B c6tXxjTnFnsF2q0hTEW252UbYDF+Y4hPbs4gho7EFSBQ9umGXXiXxE27U3hVmQE1L1bEE0 65pJqByaLzQkk2z8xIQBmoIubXa9MMY= X-MC-Unique: xFnlOB7ENlibYFWO5GkFOQ-1 X-Mimecast-MFC-AGG-ID: xFnlOB7ENlibYFWO5GkFOQ_1757358234 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 10/19] python: backport 'qmp-shell-wrap: handle missing binary gracefully' Date: Mon, 8 Sep 2025 15:03:09 -0400 Message-ID: <20250908190318.3331728-11-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358334111116600 Signed-off-by: John Snow cherry picked from commit python-qemu-qmp@9c889dcbd58817b0c917a9d2dd16161f4= 8ac8203 Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358517; cv=none; d=zohomail.com; s=zohoarc; b=Mb6mVdVyczfSaRcTtrgqOzAPMr0i4DGW0La3ir/l/xwXScUYKQuuyxwKKcZvQLlgDTGQLHU/OqkomiLonw8jA2pc0/CV+Y29A+5WsjqH5wqm565sm8GrXq+9iXV+kA48Xp3zIQdzWgJS9tNBz4xKiA7RaflathF736G/vdErdvk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358517; 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=Kfa0PcBYuaugK+IRNLZR2gp8BlYrw1GgRcJvGSJmRiQ=; b=XvyefVmT3spQvvKQSQJYyy5wRVAZmPuB7guh7iT6We72lIfcnGmkqN3Dz9rNGNDwYDmlN7cIVsk8AYNtqCT8yZFbmfwJtU3SU4tnnoCGh8k3ZkUGI/y4xYXaWdIAd7f06e63nuV6P/Kj7PRUeZd/oEOivFMxZKDpUWXUJ1wFXCI= 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 175735851723185.33176726987983; Mon, 8 Sep 2025 12:08:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAJ-0006bR-Rs; Mon, 08 Sep 2025 15:04:35 -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 1uvhAD-0006YJ-Hq for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:30 -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 1uvh9q-0007wh-D0 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:27 -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-649-Q6iCt0ZfMzuGPwlpsd5lEw-1; Mon, 08 Sep 2025 15:03:58 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 E199A1956052; Mon, 8 Sep 2025 19:03:57 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 446001955F24; Mon, 8 Sep 2025 19:03:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358240; 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=Kfa0PcBYuaugK+IRNLZR2gp8BlYrw1GgRcJvGSJmRiQ=; b=iwa7DFovIz/l6pGoJjtExlT5c9ArzH3rorx64Yqc2J5BUae92rd2g11Eby5lNYCSOIZNbB PRkpqSEl3LWqwOyCZjD8tJFkJJQHOsTI3ROLrjnB5PSXssuTWZI8nHsYtTeakt4kOTfzXj R6HWPh9aEYhFXQO8mia0pwQDo32C0wc= X-MC-Unique: Q6iCt0ZfMzuGPwlpsd5lEw-1 X-Mimecast-MFC-AGG-ID: Q6iCt0ZfMzuGPwlpsd5lEw_1757358238 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 11/19] python: backport 'qmp-tui: Do not crash if optional dependencies are not met' Date: Mon, 8 Sep 2025 15:03:10 -0400 Message-ID: <20250908190318.3331728-12-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, T_SPF_TEMPERROR=0.01 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: 1757358518203116600 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 python-qemu-qmp@df520dcacf9a75dd4c82ab1129768de41= 28b554c Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358329; cv=none; d=zohomail.com; s=zohoarc; b=VO42Hrj4GwUkOpqzP957O1ezSJfygBSxDtH4AdeXba/Y9lUNvtJxC0YRUEMqqmrL+iPrgiSvVlc2YgVkUId9joJjMFczmPBjkXXDSLnR3rbFgV8bZjb7wP+gRG6oKQZFssiw+s4799LpNljZklw7lcNycIkWhbOD5axgdFB83Ak= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358329; 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=5MThCjdQDIdDi2qFh5dFWieQhWICtc5ZN1rjsF2nwZs=; b=nD6jLMqqtliS3P0oVBSvDIQTvyl/57VeaSSwUn0PJm9EyS6Lef+xcoaiuNGWol2eqRozS4ZOWuYuTKjxgV7EXBCQsITPCNhzcvJYl8q6lfqKA4LyqIRU/ryxRcRHDyK6HdDfzWIBBcOMb2OCqlkpNO4d6itfrVRJC3LeFVLDdIA= 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 1757358329886527.9275053960101; Mon, 8 Sep 2025 12:05:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAH-0006aH-7O; Mon, 08 Sep 2025 15:04:34 -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 1uvhAA-0006Xc-Pm for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:27 -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 1uvh9q-0007xK-Ly for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:26 -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-661-bwkvMpOMPKSOJHm6bb8fGQ-1; Mon, 08 Sep 2025 15:04:02 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 F29B619560AD; Mon, 8 Sep 2025 19:04:00 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7C58E19540ED; Mon, 8 Sep 2025 19:03:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358243; 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=5MThCjdQDIdDi2qFh5dFWieQhWICtc5ZN1rjsF2nwZs=; b=WILjG8RrMABMinvN7jTYxDyFM4GcsOjZ8RILpu2kXMfzGXVKfOZQleRs+gQb7Z0yxoBcQ+ hEqGXRL4+o45Fv+J4vI+CLkuGRy6hLxiJvjtwDahXoRTw+WKazg4hdzJwP/YQ5c1ajN2/J NxmaB6+5/IjSzT5wbjbG894aNmNzLhc= X-MC-Unique: bwkvMpOMPKSOJHm6bb8fGQ-1 X-Mimecast-MFC-AGG-ID: bwkvMpOMPKSOJHm6bb8fGQ_1757358241 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 12/19] python: backport 'Remove deprecated get_event_loop calls' Date: Mon, 8 Sep 2025 15:03:11 -0400 Message-ID: <20250908190318.3331728-13-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1757358331196124100 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 python-qemu-qmp@aa1ff9907603a3033296027e1bd021133= df86ef1 Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358692; cv=none; d=zohomail.com; s=zohoarc; b=AenUcmp7WjKQr6mYlMm38gFeUs//zAinHfgjVW0Lff7wyALDmbWjEwQAN4S+eK+AU+j28EVZg3wTD2waL2tqj6HLiIf8cPwvJzkWhpC+tlH63EvAXfaxuYrAQAc8TZ3MeygTXZR/k3IQayogv1+shWzKBAgh1kTFjVIiaKsQDKg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358692; 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=3BfWxpJbAnJ9d6T+UkvBd172fXR82WSe+8/48aB6pko=; b=n6Rqj4sswppX9eMIJ9Ll0oMGJH5kYql1gfogl9JSdbs/MFiBQV7SVOoa8nXbTDLbQSp6wiwHp5XqpNZSTuHuRJ9N+uMJopr/PJNZQc2ZAUv6iMPF1JhPrkSanMaeRBZ4SwMQtuWq4DNMjrZ6G5NZKXGSALLJNlbErH7VMmDtaoM= 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 1757358692083533.1106034382192; Mon, 8 Sep 2025 12:11:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAN-0006cd-3r; Mon, 08 Sep 2025 15:04: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 1uvhAH-0006ax-Q6 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:33 -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 1uvh9v-0007ya-Fj for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:33 -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-232-cs67CJxrNPK1e2d0UESlbA-1; Mon, 08 Sep 2025 15:04:05 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 5A38219560A2; Mon, 8 Sep 2025 19:04:04 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8DC4F1955F24; Mon, 8 Sep 2025 19:04:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358248; 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=3BfWxpJbAnJ9d6T+UkvBd172fXR82WSe+8/48aB6pko=; b=P2HRNj5nncbDEgKUDmIVX8ysylPrtbp2cXHZNrLVZ/lsWbj76W1A5Sgyh7HIiKyqfn+9YO cKHMSfh/Szwn7aSxeFI+S5fdSP12QukgiYm1BG6iAZ+UrrK+qu9A+YIZyOup8ZFC0AL39K 2/6ACZTOvEjo1cUJQLQ/fZAFsGgIl1g= X-MC-Unique: cs67CJxrNPK1e2d0UESlbA-1 X-Mimecast-MFC-AGG-ID: cs67CJxrNPK1e2d0UESlbA_1757358244 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa , "Richard W.M. Jones" Subject: [PATCH v3 13/19] python: backport 'avoid creating additional event loops per thread' Date: Mon, 8 Sep 2025 15:03:12 -0400 Message-ID: <20250908190318.3331728-14-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358694830124100 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 python-qemu-qmp@21ce2ee4f2df87efe84a27b9c5112487f= 4670622 cherry picked from commit python-qemu-qmp@c08fb82b38212956ccffc03fc6d015c39= 79f42fe Signed-off-by: John Snow Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358547; cv=none; d=zohomail.com; s=zohoarc; b=EakNSoo7A7l719Ke19/KwdmYfQZYW+ZFXX2AbBDw2Glt8fs9I9MByJP4Z4XNK6wfjvTEFIIBAmWs/9e/Gzrq0mtO7XMGSTTXpy63ubDckk0i3zWoeJq1S11Bbt7WhB7M/5OezPRy8HpfhZkjHsfvuiK+8e0JmCtghXvA3weDmjY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358547; 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=j/d5m/iVEv+hPaSprusYXgmSpKRi2nODs9d1kNw8Vd0=; b=LkEiRxLKBoevr+zHMVOKo8VKLbLBS6cQPtR6NdI79zOYvWPael8Pcvp1FAmxETu+3ce97aVvJc4o1ZCt9NGXHYAZr3t23OIQMs4Z22ncIpdVJnK5t/8db1cZABQ0UIj1XNh6R85oFQu+Mqrr76aV63ptV4qnx+vbvTQ2ftjePyo= 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 1757358547822204.81775028935624; Mon, 8 Sep 2025 12:09:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAP-0006ek-Qp; Mon, 08 Sep 2025 15:04:42 -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 1uvhAO-0006ds-Ov for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:40 -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 1uvhA1-0007zB-Sj for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:40 -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-478-7D-N2bl8Ol2HSaLaoJUMCg-1; Mon, 08 Sep 2025 15:04:09 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 89D6E19560B5; Mon, 8 Sep 2025 19:04:08 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EA2D71955F24; Mon, 8 Sep 2025 19:04:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358252; 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=j/d5m/iVEv+hPaSprusYXgmSpKRi2nODs9d1kNw8Vd0=; b=OfItkD/e0B+QQ5GECDTiVbKpYsSWP5aNYsY+rXTWkAnlPC4GgwqRRqSHFDscfYM9hEznaY am4zW/+QMAI70CNo5rOzJdUL+0Q3//qrd4xsgv6qQaRpcf+vVJbEv+nD0qO+25kT3qYow6 LSQEiMVb31ewUkbSX2URKUlQpEADp7o= X-MC-Unique: 7D-N2bl8Ol2HSaLaoJUMCg-1 X-Mimecast-MFC-AGG-ID: 7D-N2bl8Ol2HSaLaoJUMCg_1757358248 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 14/19] python: synchronize qemu.qmp documentation Date: Mon, 8 Sep 2025 15:03:13 -0400 Message-ID: <20250908190318.3331728-15-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358548678116600 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 Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 Wed Sep 10 01:54:45 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=1757358511; cv=none; d=zohomail.com; s=zohoarc; b=cWzSxpsm0tkCRDZFoN/Eu+qGUOWUXTNyDCqG8s1WLgCd3yBHm3hfWx6PKzoB9AYWJztt1Zdg6F9LzTkula/0jY4TtlLmloalxM1HkPfS9Dzwesez9Zm1YGRTU5PrIhRgPUlpPc/E/ZAIWmCMf1BJM9MsNWW2R1ms9MyUxbXUwlc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358511; 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=Gf1LCi3D0SWjwe2WBIljGWEUnbmdHfdZ0WSLpZRWvFDZwZx6Xn4BS7AfYJlDrpQxSlSNduiEiWeJNXm10t51Gwlt4MMMwciQCbMKy38vUueUlvD3F8rayK3O5X1rvTBmWqrGmpnLBfJOuLlRcLZemXQO3LgI1gxfpi5c6RoMV0k= 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 1757358511770217.57235530386959; Mon, 8 Sep 2025 12:08:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAO-0006dq-PZ; Mon, 08 Sep 2025 15:04:40 -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 1uvhAM-0006dH-Tw for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:38 -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 1uvhA3-0007zO-L7 for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:38 -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-683-kRY7pw9tOZWXJEUCHzG73g-1; Mon, 08 Sep 2025 15:04:12 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 7A1BE1956089; Mon, 8 Sep 2025 19:04:11 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0D8191955F24; Mon, 8 Sep 2025 19:04:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358253; 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=jNOt766zVLfhHTE2uGNqS7+7IQZrlDpXQ7/OA4fGw/utry04JH+reKCdFmu4MgMsPD8vVt 5Sq8M8cPQoGi+F7u32jM08wuUMx67kCkp3R7sA21wZoMkxVHah9Sl/wHyqULowsp1lKhKH ZmsceU/ROx1WDPuLfr28ptsf0q/iRQY= X-MC-Unique: kRY7pw9tOZWXJEUCHzG73g-1 X-Mimecast-MFC-AGG-ID: kRY7pw9tOZWXJEUCHzG73g_1757358251 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 15/19] iotests: drop compat for old version context manager Date: Mon, 8 Sep 2025 15:03:14 -0400 Message-ID: <20250908190318.3331728-16-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358512847124100 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 Wed Sep 10 01:54:45 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=1757358895; cv=none; d=zohomail.com; s=zohoarc; b=et1ezx8rFBTHVoq2LpvvQGpqAHWcQlM06eA74SL6aghN2HMGkX8rlXdYRsD0Ocf2uAI7ZURjjd9cY8Sps1TLWwL90QP7VnB02IDqT7OrcCB96Y+IKmLgkZQ5wN7NZR5+7EmXxz85YBq3FFzsoMV/fgPTeudP55Zd85U4CudBRa8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358895; 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=FQZCV3BYSLr02XR9Kk3GPKP7MOL7VzwN2C4MCuKqzw4i4P5CUFGf0mQaIg7ZpFfsGm89Lcz0h61Kq6ZCoM8FtsYRzB8h0WgJ7sv9cW8iXjlGbwwc1JwJVi2ankLnHumIt3tdyaLt2gGUg6/iDWeiL1qKqX/RgVOe5+O5Mb09Q3w= 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 175735889537698.13444090569271; Mon, 8 Sep 2025 12:14:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAX-0006iH-AY; Mon, 08 Sep 2025 15:04:49 -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 1uvhAS-0006fb-Ea for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:44 -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 1uvhA3-000807-7Z for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:44 -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-526-2jaTw49gMIqOcP0wtRb6Pg-1; Mon, 08 Sep 2025 15:04:15 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 B36241955F3D; Mon, 8 Sep 2025 19:04:14 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 03D1A19540EE; Mon, 8 Sep 2025 19:04:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358256; 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=UrnkXYtQ2Bynj+yyuZYKMRV4D4bH7K3d2ANBZ61kSilhrOnHDSOJPL2INqsFuBb8wUN1kx TPSRO2keN6q/mcIlHpdmq/tBwXrnucuaa7+8fS1b7af3T7eV1zEonEiNewymyzNZs9RMfO dTrVX66a9a/eXyGJtzqSj3XJ0HJcCA4= X-MC-Unique: 2jaTw49gMIqOcP0wtRb6Pg-1 X-Mimecast-MFC-AGG-ID: 2jaTw49gMIqOcP0wtRb6Pg_1757358254 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 16/19] python: ensure QEMUQtestProtocol closes its socket Date: Mon, 8 Sep 2025 15:03:15 -0400 Message-ID: <20250908190318.3331728-17-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358896186116600 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 Wed Sep 10 01:54:45 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=1757358808; cv=none; d=zohomail.com; s=zohoarc; b=Y+iHInGrVWFVILfQmjr2W1g8dcX9irlFT283Ql11s0x80kc9F1htNIz88ssKFWKTYuRhOjZJUxH49jFtkKk9neUfSHR6mi9aE1drsKBMw1ypOyqDx/Kvc8NhmSlHFiKJADh8eOYHT8iqg9oEDlhHSwd63DxvoU4Mphjhykr3e3Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358808; 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=IRstvp01LEwBNBfIE17r/tzgJsORJL7YF/Mj9NsSYUNgfbVt7FXjsePu41s2PBGB1o61hfw9lsVn1UMywe4/TrDSHP0KRJidit7hdYzBSaxi40Y7AQpxRS2ioS2ARtztnONGu2i5qewiBnzSEHVuIuZEtncBysSb/IEuPlSnneU= 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 1757358808421241.29047792887002; Mon, 8 Sep 2025 12:13:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAX-0006iM-UY; Mon, 08 Sep 2025 15:04:50 -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 1uvhAV-0006hY-QA for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:47 -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 1uvhAB-000815-QY for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:47 -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-211-hzF_iemFM-S9arKnUtyMag-1; Mon, 08 Sep 2025 15:04:18 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 80D1719560A1; Mon, 8 Sep 2025 19:04:17 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3CEFE1955F24; Mon, 8 Sep 2025 19:04:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358260; 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=Ogp+HOnDAEXYWv3+73V1ijmr4bhOzw3OWZ0Jo92BVJmrqA+h10EJ/C0Ww3CKSUrX16UQvu UgP6Nb3QBqZcJhNj1nHVKxDjTux5JuqqsE7ivUe90JFdgxiLVCZ66d29iPAu0BmaNjDIPa QByUVmQ8UrvQ0oOhligktcMOMbHiGXg= X-MC-Unique: hzF_iemFM-S9arKnUtyMag-1 X-Mimecast-MFC-AGG-ID: hzF_iemFM-S9arKnUtyMag_1757358257 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 17/19] iotests/147: ensure temporary sockets are closed before exiting Date: Mon, 8 Sep 2025 15:03:16 -0400 Message-ID: <20250908190318.3331728-18-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358809176116600 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 Wed Sep 10 01:54:45 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=1757358394; cv=none; d=zohomail.com; s=zohoarc; b=PGVQL3eJKu1rQfIzRHd4qqfhWAYiqDI3uV2H6w1OFl0PIrTbwhUZK09GNW7Q11FJGeKCQESkyL4c3j2WZEKfxbeGoH5SbUcUJe3YwNWdsQgtOBWDswMArRiFYSgAJo8BY4S8NeDqObx04G+Rn3OvugsuDbEWCmqn+7J+N0d7XDY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358394; 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=nSJZMFMbXh+yyVrGhVTvBx3hcDvOJ34vFxrT0P5PaTT9quhLZVAyJkEn0nev/ms2fBhGbjEYRp4+8ytZkUpAoFxRC0BplbtZs4szW48wpoMSE9ctViIKlheH6vOelqTkrphqLQWtaQg+RvEA/Qk2GakFTt3P3myeM5NOBXrMqwc= 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 1757358394551854.991729437906; Mon, 8 Sep 2025 12:06:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAV-0006hZ-UA; Mon, 08 Sep 2025 15:04:48 -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 1uvhAT-0006fZ-Dh for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:45 -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 1uvhAB-00081t-DD for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:43 -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-618-lU-D3NSkMAyoPaSZMQ4M_A-1; Mon, 08 Sep 2025 15:04:21 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 CCCEA18004D8; Mon, 8 Sep 2025 19:04:20 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2B2E21955F24; Mon, 8 Sep 2025 19:04:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358264; 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=HSiS36H37dOdgfy7wtEd8PBi6a+96SqbqFZHDDuP0QGo8K1EHMHKRSYbbRmFQ8uExvr18D vi1/WJkt7wY8POxltlC6wEFDzfZYdvtJrw+a5E0Rsy23aJNwLd+GqCje31nfRa6Nu3e5JV 5620Ol+RuFx9DbVrlLlmrAyWr+Xc+t8= X-MC-Unique: lU-D3NSkMAyoPaSZMQ4M_A-1 X-Mimecast-MFC-AGG-ID: lU-D3NSkMAyoPaSZMQ4M_A_1757358260 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 18/19] iotests/151: ensure subprocesses are cleaned up Date: Mon, 8 Sep 2025 15:03:17 -0400 Message-ID: <20250908190318.3331728-19-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358396693116600 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 Wed Sep 10 01:54:45 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=1757358660; cv=none; d=zohomail.com; s=zohoarc; b=dOZR6r0lvJEq63GIl4xPIYmYGRoUAd3rpjO/vy/3o1y2gwwAGfkVwKTaEzo52RXAJYBjz/uYQTMjLyR0nM6scZiqWvJ1TLBzb5ri6q29e95qzIIW63HF4EAOFKhThWMhQ4LHX/b9sgYU0rlGNkur91VjJ6cizHPFc4xIVCYha2w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757358660; 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=MeK2PzQZ0Iq5fC2/ZnDL9HLL7jd+ys7L9fG5+hf/d+RuDXLRKXobFlHFNV6uAGgnIXbG6m7HApQZmE0yf/hsUyAncJY5IdVC7HgrI/IoOkPtZKmEgs5MsTDj39dWG1kf6UqdC20/gH5nRF8OkKK7Gccc6yMZjQ3bpx/3Anemn3g= 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 1757358660945661.0737487389404; Mon, 8 Sep 2025 12:11:00 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uvhAc-0006jX-7c; Mon, 08 Sep 2025 15:04: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 1uvhAX-0006iG-6m for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04: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 1uvhAE-00081z-Vs for qemu-devel@nongnu.org; Mon, 08 Sep 2025 15:04:48 -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-118-ak7TW2aLNy2hNkY1swWsyQ-1; Mon, 08 Sep 2025 15:04:24 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 088201800298; Mon, 8 Sep 2025 19:04:24 +0000 (UTC) Received: from jsnow-thinkpadp16vgen1.westford.csb (unknown [10.22.88.36]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3B3FD19540ED; Mon, 8 Sep 2025 19:04:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1757358265; 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=LeFdZzVw0kIVmeqT6VSaiH7ibXVeHplgS+D0NB077MvDr2zvU+osnVeDylQca5TMQrdvBj e3ZRAuD4Z7B4wI+hOsh+NzTzZNjRU+QNuG64i3hZqJ6IfZbl4dtLOkFvNbyTUpg1dXbf9x Mo2LMepbcZbewryxG/+sdFsnSPIv5iI= X-MC-Unique: ak7TW2aLNy2hNkY1swWsyQ-1 X-Mimecast-MFC-AGG-ID: ak7TW2aLNy2hNkY1swWsyQ_1757358264 From: John Snow To: qemu-devel@nongnu.org Cc: Kevin Wolf , qemu-block@nongnu.org, =?UTF-8?q?Daniel=20Berrang=C3=A9?= , Hanna Reitz , John Snow , Cleber Rosa Subject: [PATCH v3 19/19] iotests/check: always enable all python warnings Date: Mon, 8 Sep 2025 15:03:18 -0400 Message-ID: <20250908190318.3331728-20-jsnow@redhat.com> In-Reply-To: <20250908190318.3331728-1-jsnow@redhat.com> References: <20250908190318.3331728-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.17 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_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_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: 1757358662338124100 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