From patchwork Wed Apr 24 08:16:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641495 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0B1A2C4345F for ; Wed, 24 Apr 2024 08:17:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXoc-0000Lg-8h; Wed, 24 Apr 2024 04:17:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXob-0000LM-0y for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17: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 1rzXoZ-0006Lq-9O for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946634; 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=TB5l2rwrHH42yLHxk8SVx9DTgLa86AXV+VzmrSBXEQ0=; b=eZ2PbirdwzRFn+PQ4jypoJijPNoFfCoiKovmRIVwzkk41nhNTqqmEQoekW0GjoEFCRjPAC cdyulrHTrSnIw9Z8WpjQ0ZpNgdZ0I8OPXzY99ok5sZI/Ctd+F81M/toXPBtYVNajtjaYER 6ydCOHh/dzyaR30jVXZ9K31pFSlzDjQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-544-eiKmmE55O0CVEyFWSyUxWA-1; Wed, 24 Apr 2024 04:17:12 -0400 X-MC-Unique: eiKmmE55O0CVEyFWSyUxWA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id EDA4F811000; Wed, 24 Apr 2024 08:17:11 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CEED71C060D0; Wed, 24 Apr 2024 08:17:11 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id C64D421E668A; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 01/25] qapi/parser: fix typo - self.returns.info => self.errors.info Date: Wed, 24 Apr 2024 10:16:46 +0200 Message-ID: <20240424081710.2907748-2-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Small copy-pasto. The correct info field to use in this conditional block is self.errors.info. Fixes: 3a025d3d1ffa Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-2-armbru@redhat.com> --- scripts/qapi/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index d8f76060b8..fed88e9074 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -733,7 +733,7 @@ def check_expr(self, expr: QAPIExpression) -> None: "'Returns' section is only valid for commands") if self.errors: raise QAPISemError( - self.returns.info, + self.errors.info, "'Errors' section is only valid for commands") def check(self) -> None: From patchwork Wed Apr 24 08:16:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641502 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 69D5EC4345F for ; Wed, 24 Apr 2024 08:18:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXp3-0000iU-KO; Wed, 24 Apr 2024 04:17:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXod-0000My-T8 for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -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 1rzXoa-0006MJ-OM for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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=fVJ3VfeNla0b1aH7kFiMHnp6SE+Kn03Pe0CfNwIitno=; b=MbvWDQO3uEdsZeSw5IMHAjyKhEfxGqvsDA1T5j7fC6ToxYQQqNns9qGtuvruLHu48tHqmQ u/FoUvfSoc1vE0yxc4y/6VhhSMSWC/+ggxgmgJWqcH/dkA8QkZo+mTXCr1iyWMXQeWGdIv twUsza9jRnDBa1XnUJItaXh4QetLWMg= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-587-IX5_LUvMOnWnVYMAXZmrQw-1; Wed, 24 Apr 2024 04:17:12 -0400 X-MC-Unique: IX5_LUvMOnWnVYMAXZmrQw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id EE57E3806272; Wed, 24 Apr 2024 08:17:11 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CF391C08EE0; Wed, 24 Apr 2024 08:17:11 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id C905E21E6690; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 02/25] qapi/parser: shush up pylint Date: Wed, 24 Apr 2024 10:16:47 +0200 Message-ID: <20240424081710.2907748-3-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Shhh! Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-3-armbru@redhat.com> --- scripts/qapi/parser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index fed88e9074..ec4ebef4e3 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -607,6 +607,7 @@ class QAPIDoc: """ class Section: + # pylint: disable=too-few-public-methods def __init__(self, info: QAPISourceInfo, tag: Optional[str] = None): # section source info, i.e. where it begins From patchwork Wed Apr 24 08:16:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641504 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 869B2C10F15 for ; Wed, 24 Apr 2024 08:18:47 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpB-00018s-9v; Wed, 24 Apr 2024 04:17:53 -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 1rzXoe-0000N3-1H for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:20 -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 1rzXob-0006MX-4M for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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=okQXhM5EdV4nJ/xGs2usfi2oSxOw1NGs7cFrvbXnFKA=; b=BPFKjjZoupC5gmuktDm2CR26xP4g5sIMD51X3nl720HpGlYKxuQ1iudr8orNyt9wvSuYRn F1/ZeflbWYVnhluw5BMPJLU4EjWsZJ9Qn45t9pB7aTrZ/eLEVuEC+pTAUwC/9LryqS0pT0 M+mUTc5oMXzvDUq7Uq5Ifv9CASQOGIQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-20-qNUjfTvCOUS3PDl__OCwpg-1; Wed, 24 Apr 2024 04:17:12 -0400 X-MC-Unique: qNUjfTvCOUS3PDl__OCwpg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2C17F812C55; Wed, 24 Apr 2024 08:17:12 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0C3B78C4; Wed, 24 Apr 2024 08:17:12 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id CC05821E669B; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 03/25] qapi: sort pylint suppressions Date: Wed, 24 Apr 2024 10:16:48 +0200 Message-ID: <20240424081710.2907748-4-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Suggested-by: Markus Armbruster Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-4-armbru@redhat.com> --- scripts/qapi/pylintrc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/qapi/pylintrc b/scripts/qapi/pylintrc index 90546df534..1342412c3c 100644 --- a/scripts/qapi/pylintrc +++ b/scripts/qapi/pylintrc @@ -16,13 +16,13 @@ ignore-patterns=schema.py, # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". -disable=fixme, +disable=consider-using-f-string, + fixme, missing-docstring, too-many-arguments, too-many-branches, - too-many-statements, too-many-instance-attributes, - consider-using-f-string, + too-many-statements, useless-option-value, [REPORTS] From patchwork Wed Apr 24 08:16:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641512 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CB8EDC4345F for ; Wed, 24 Apr 2024 08:20:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpE-0001J1-CZ; Wed, 24 Apr 2024 04:17:56 -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 1rzXoc-0000Lm-HM for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:18 -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 1rzXoa-0006MB-92 for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946635; 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=VNjgmhzSB7f+n+iWYXPzQcQrVJoZVSDzsuVJvF8EmrU=; b=K7e2SBni1a3lnmIM40BQT4Rydv+0deBTrEiR62kN6IroEhBjrx4HlJIpvtCY0aO785BNvw qyWN1syyDZTsNnJEdaxBy7YCIlcby6QVuK4UI8iCaklY7m7l7FkGIUBHjjY91SF8eI6XKM t/Ix6FYTTkFW3o0GtYGQ0h3yHyhjwo0= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-546-MrsGbSbxO_yJ91MAC4Uiwg-1; Wed, 24 Apr 2024 04:17:12 -0400 X-MC-Unique: MrsGbSbxO_yJ91MAC4Uiwg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id EDF8E1C05AA0; Wed, 24 Apr 2024 08:17:11 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CF0AF44047; Wed, 24 Apr 2024 08:17:11 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id CEF6621E669C; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 04/25] qapi/schema: add pylint suppressions Date: Wed, 24 Apr 2024 10:16:49 +0200 Message-ID: <20240424081710.2907748-5-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow With this patch, pylint is happy with the file, so enable it in the configuration. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-5-armbru@redhat.com> --- scripts/qapi/pylintrc | 5 ----- scripts/qapi/schema.py | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/qapi/pylintrc b/scripts/qapi/pylintrc index 1342412c3c..c028a1f9f5 100644 --- a/scripts/qapi/pylintrc +++ b/scripts/qapi/pylintrc @@ -1,10 +1,5 @@ [MASTER] -# Add files or directories matching the regex patterns to the ignore list. -# The regex matches against base names, not paths. -ignore-patterns=schema.py, - - [MESSAGES CONTROL] # Disable the message, report, category or checker with the given id(s). You diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 8ba5665bc6..117f0f78f0 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -12,6 +12,8 @@ # This work is licensed under the terms of the GNU GPL, version 2. # See the COPYING file in the top-level directory. +# pylint: disable=too-many-lines + # TODO catching name collisions in generated code would be nice from collections import OrderedDict @@ -83,6 +85,7 @@ def c_name(self): return c_name(self.name) def check(self, schema): + # pylint: disable=unused-argument assert not self._checked seen = {} for f in self.features: @@ -113,6 +116,7 @@ def is_implicit(self): return not self.info def visit(self, visitor): + # pylint: disable=unused-argument assert self._checked def describe(self): @@ -131,6 +135,7 @@ def visit_module(self, name): pass def visit_needed(self, entity): + # pylint: disable=unused-argument # Default to visiting everything return True From patchwork Wed Apr 24 08:16:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641509 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C75FDC4345F for ; Wed, 24 Apr 2024 08:19:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpF-0001JU-2D; Wed, 24 Apr 2024 04:17:57 -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 1rzXor-0000WR-S2 for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:39 -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 1rzXon-0006QB-Tl for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946646; 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=DHuF+6bADCra9wf2vBE0U5Uu02Pkv4J6hK2ImEsHpf0=; b=Aceq/rO/n3CoFHVPffzSo2Umjqwrw+0ppeHO0/ErfyVTNU1BSfiUSPyeJPq1BNxKF2+1rd nNwtrG5N1VuBnU21IaAwiR6cw3USZmjJaer9pB8zFqCfspFYOkNA2LMJS+362KYLLw3bGi KnePQEx1OBvdatvYb/gK8yPQNgjPEB8= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-552-yjZUgU8vPoq1UiNu1Y3R5g-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: yjZUgU8vPoq1UiNu1Y3R5g-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 618253806274; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0D0A1581DE; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id D20F221E66A7; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 05/25] qapi: create QAPISchemaDefinition Date: Wed, 24 Apr 2024 10:16:50 +0200 Message-ID: <20240424081710.2907748-6-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Include entities don't have names, but we generally expect "entities" to have names. Reclassify all entities with names as *definitions*, leaving the nameless include entities as QAPISchemaEntity instances. This is primarily to help simplify typing around expectations of what callers expect for properties of an "entity". Suggested-by: Markus Armbruster Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-6-armbru@redhat.com> --- scripts/qapi/schema.py | 144 +++++++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 62 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 117f0f78f0..b298c8b4f9 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -55,14 +55,13 @@ def is_present(self): class QAPISchemaEntity: - meta: Optional[str] = None + """ + A schema entity. - def __init__(self, name: str, info, doc, ifcond=None, features=None): - assert name is None or isinstance(name, str) - for f in features or []: - assert isinstance(f, QAPISchemaFeature) - f.set_defined_in(name) - self.name = name + This is either a directive, such as include, or a definition. + The latter uses sub-class `QAPISchemaDefinition`. + """ + def __init__(self, info): self._module = None # For explicitly defined entities, info points to the (explicit) # definition. For builtins (and their arrays), info is None. @@ -70,33 +69,17 @@ def __init__(self, name: str, info, doc, ifcond=None, features=None): # triggered the implicit definition (there may be more than one # such place). self.info = info - self.doc = doc - self._ifcond = ifcond or QAPISchemaIfCond() - self.features = features or [] self._checked = False def __repr__(self): - if self.name is None: - return "<%s at 0x%x>" % (type(self).__name__, id(self)) - return "<%s:%s at 0x%x>" % (type(self).__name__, self.name, - id(self)) - - def c_name(self): - return c_name(self.name) + return "<%s at 0x%x>" % (type(self).__name__, id(self)) def check(self, schema): # pylint: disable=unused-argument - assert not self._checked - seen = {} - for f in self.features: - f.check_clash(self.info, seen) self._checked = True def connect_doc(self, doc=None): - doc = doc or self.doc - if doc: - for f in self.features: - doc.connect_feature(f) + pass def _set_module(self, schema, info): assert self._checked @@ -107,6 +90,46 @@ def _set_module(self, schema, info): def set_module(self, schema): self._set_module(schema, self.info) + def visit(self, visitor): + # pylint: disable=unused-argument + assert self._checked + + +class QAPISchemaDefinition(QAPISchemaEntity): + meta: Optional[str] = None + + def __init__(self, name: str, info, doc, ifcond=None, features=None): + assert isinstance(name, str) + super().__init__(info) + for f in features or []: + assert isinstance(f, QAPISchemaFeature) + f.set_defined_in(name) + self.name = name + self.doc = doc + self._ifcond = ifcond or QAPISchemaIfCond() + self.features = features or [] + + def __repr__(self): + return "<%s:%s at 0x%x>" % (type(self).__name__, self.name, + id(self)) + + def c_name(self): + return c_name(self.name) + + def check(self, schema): + assert not self._checked + super().check(schema) + seen = {} + for f in self.features: + f.check_clash(self.info, seen) + + def connect_doc(self, doc=None): + super().connect_doc(doc) + doc = doc or self.doc + if doc: + for f in self.features: + doc.connect_feature(f) + @property def ifcond(self): assert self._checked @@ -115,10 +138,6 @@ def ifcond(self): def is_implicit(self): return not self.info - def visit(self, visitor): - # pylint: disable=unused-argument - assert self._checked - def describe(self): assert self.meta return "%s '%s'" % (self.meta, self.name) @@ -218,7 +237,7 @@ def visit(self, visitor): class QAPISchemaInclude(QAPISchemaEntity): def __init__(self, sub_module, info): - super().__init__(None, info, None) + super().__init__(info) self._sub_module = sub_module def visit(self, visitor): @@ -226,7 +245,7 @@ def visit(self, visitor): visitor.visit_include(self._sub_module.name, self.info) -class QAPISchemaType(QAPISchemaEntity): +class QAPISchemaType(QAPISchemaDefinition): # Return the C type for common use. # For the types we commonly box, this is a pointer type. def c_type(self): @@ -797,7 +816,7 @@ def __init__(self, name, info, typ, ifcond=None): super().__init__(name, info, typ, False, ifcond) -class QAPISchemaCommand(QAPISchemaEntity): +class QAPISchemaCommand(QAPISchemaDefinition): meta = 'command' def __init__(self, name, info, doc, ifcond, features, @@ -868,7 +887,7 @@ def visit(self, visitor): self.coroutine) -class QAPISchemaEvent(QAPISchemaEntity): +class QAPISchemaEvent(QAPISchemaDefinition): meta = 'event' def __init__(self, name, info, doc, ifcond, features, arg_type, boxed): @@ -939,23 +958,24 @@ def __init__(self, fname): self.check() def _def_entity(self, ent): - # Only the predefined types are allowed to not have info - assert ent.info or self._predefining self._entity_list.append(ent) - if ent.name is None: - return + + def _def_definition(self, defn): + # Only the predefined types are allowed to not have info + assert defn.info or self._predefining + self._def_entity(defn) # TODO reject names that differ only in '_' vs. '.' vs. '-', # because they're liable to clash in generated C. - other_ent = self._entity_dict.get(ent.name) - if other_ent: - if other_ent.info: - where = QAPISourceError(other_ent.info, "previous definition") + other_defn = self._entity_dict.get(defn.name) + if other_defn: + if other_defn.info: + where = QAPISourceError(other_defn.info, "previous definition") raise QAPISemError( - ent.info, - "'%s' is already defined\n%s" % (ent.name, where)) + defn.info, + "'%s' is already defined\n%s" % (defn.name, where)) raise QAPISemError( - ent.info, "%s is already defined" % other_ent.describe()) - self._entity_dict[ent.name] = ent + defn.info, "%s is already defined" % other_defn.describe()) + self._entity_dict[defn.name] = defn def lookup_entity(self, name, typ=None): ent = self._entity_dict.get(name) @@ -997,7 +1017,7 @@ def _def_include(self, expr: QAPIExpression): QAPISchemaInclude(self._make_module(include), expr.info)) def _def_builtin_type(self, name, json_type, c_type): - self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type)) + self._def_definition(QAPISchemaBuiltinType(name, json_type, c_type)) # Instantiating only the arrays that are actually used would # be nice, but we can't as long as their generated code # (qapi-builtin-types.[ch]) may be shared by some other @@ -1023,15 +1043,15 @@ def _def_predefineds(self): self._def_builtin_type(*t) self.the_empty_object_type = QAPISchemaObjectType( 'q_empty', None, None, None, None, None, [], None) - self._def_entity(self.the_empty_object_type) + self._def_definition(self.the_empty_object_type) qtypes = ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] qtype_values = self._make_enum_members( [{'name': n} for n in qtypes], None) - self._def_entity(QAPISchemaEnumType('QType', None, None, None, None, - qtype_values, 'QTYPE')) + self._def_definition(QAPISchemaEnumType( + 'QType', None, None, None, None, qtype_values, 'QTYPE')) def _make_features(self, features, info): if features is None: @@ -1053,7 +1073,8 @@ def _make_enum_members(self, values, info): def _make_array_type(self, element_type, info): name = element_type + 'List' # reserved by check_defn_name_str() if not self.lookup_type(name): - self._def_entity(QAPISchemaArrayType(name, info, element_type)) + self._def_definition(QAPISchemaArrayType( + name, info, element_type)) return name def _make_implicit_object_type(self, name, info, ifcond, role, members): @@ -1068,7 +1089,7 @@ def _make_implicit_object_type(self, name, info, ifcond, role, members): # later. pass else: - self._def_entity(QAPISchemaObjectType( + self._def_definition(QAPISchemaObjectType( name, info, None, ifcond, None, None, members, None)) return name @@ -1079,7 +1100,7 @@ def _def_enum_type(self, expr: QAPIExpression): ifcond = QAPISchemaIfCond(expr.get('if')) info = expr.info features = self._make_features(expr.get('features'), info) - self._def_entity(QAPISchemaEnumType( + self._def_definition(QAPISchemaEnumType( name, info, expr.doc, ifcond, features, self._make_enum_members(data, info), prefix)) @@ -1107,7 +1128,7 @@ def _def_struct_type(self, expr: QAPIExpression): info = expr.info ifcond = QAPISchemaIfCond(expr.get('if')) features = self._make_features(expr.get('features'), info) - self._def_entity(QAPISchemaObjectType( + self._def_definition(QAPISchemaObjectType( name, info, expr.doc, ifcond, features, base, self._make_members(data, info), None)) @@ -1137,7 +1158,7 @@ def _def_union_type(self, expr: QAPIExpression): info) for (key, value) in data.items()] members: List[QAPISchemaObjectTypeMember] = [] - self._def_entity( + self._def_definition( QAPISchemaObjectType(name, info, expr.doc, ifcond, features, base, members, QAPISchemaVariants( @@ -1156,7 +1177,7 @@ def _def_alternate_type(self, expr: QAPIExpression): info) for (key, value) in data.items()] tag_member = QAPISchemaObjectTypeMember('type', info, 'QType', False) - self._def_entity( + self._def_definition( QAPISchemaAlternateType( name, info, expr.doc, ifcond, features, QAPISchemaVariants(None, info, tag_member, variants))) @@ -1181,11 +1202,10 @@ def _def_command(self, expr: QAPIExpression): if isinstance(rets, list): assert len(rets) == 1 rets = self._make_array_type(rets[0], info) - self._def_entity(QAPISchemaCommand(name, info, expr.doc, ifcond, - features, data, rets, - gen, success_response, - boxed, allow_oob, allow_preconfig, - coroutine)) + self._def_definition( + QAPISchemaCommand(name, info, expr.doc, ifcond, features, data, + rets, gen, success_response, boxed, allow_oob, + allow_preconfig, coroutine)) def _def_event(self, expr: QAPIExpression): name = expr['event'] @@ -1198,8 +1218,8 @@ def _def_event(self, expr: QAPIExpression): data = self._make_implicit_object_type( name, info, ifcond, 'arg', self._make_members(data, info)) - self._def_entity(QAPISchemaEvent(name, info, expr.doc, ifcond, - features, data, boxed)) + self._def_definition(QAPISchemaEvent(name, info, expr.doc, ifcond, + features, data, boxed)) def _def_exprs(self, exprs): for expr in exprs: From patchwork Wed Apr 24 08:16:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641525 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4F35CC4345F for ; Wed, 24 Apr 2024 08:22:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpC-0001Gp-8a; Wed, 24 Apr 2024 04:17: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 1rzXog-0000PD-Pg for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:29 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXoc-0006NN-Np for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946637; 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=q3PB96E5geOcilAlxYVVbJAYbBbSyK2NOflBBzkZQT4=; b=JXJF2HwqQUiiK/lT4rTkKp9E8zeMaSF7DUiFZMeBKZfwoWIvecP0JWcr/TdTmuOq+cYz09 qrE1Qm5xIZuzt4UI1t5+DgVNX6A2HqsR4E4gCC04G+2TxybLb1Fnd1MOhcEvGXXHXhZmQn ziQvEbT+h6TGtYNXEmK/g0hhKtlLEHc= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-601-rPfsceHKO2Cwn-MZZ7ufXA-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: rPfsceHKO2Cwn-MZZ7ufXA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2B28318065AF; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0CBBA112132A; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id D537121E66AB; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 06/25] qapi/schema: declare type for QAPISchemaObjectTypeMember.type Date: Wed, 24 Apr 2024 10:16:51 +0200 Message-ID: <20240424081710.2907748-7-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow A QAPISchemaObjectTypeMember's type gets resolved only during .check(). We have QAPISchemaObjectTypeMember.__init__() initialize self.type = None, and .check() assign the actual type. Using .type before .check() is wrong, and hopefully crashes due to the value being None. Works. However, it makes for awkward typing. With .type: Optional[QAPISchemaType], mypy is of course unable to see that it's None before .check(), and a QAPISchemaType after. To help it over the hump, we'd have to assert self.type is not None before all the (valid) uses. The assertion catches invalid uses, but only at run time; mypy can't flag them. Instead, declare .type in .__init__() as QAPISchemaType *without* initializing it. Using .type before .check() now certainly crashes, which is an improvement. Mypy still can't flag invalid uses, but that's okay. Addresses typing errors such as these: qapi/schema.py:657: error: "None" has no attribute "alternate_qtype" [attr-defined] qapi/schema.py:662: error: "None" has no attribute "describe" [attr-defined] Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-7-armbru@redhat.com> --- scripts/qapi/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index b298c8b4f9..307f8af01a 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -786,7 +786,7 @@ def __init__(self, name, info, typ, optional, ifcond=None, features=None): assert isinstance(f, QAPISchemaFeature) f.set_defined_in(name) self._type_name = typ - self.type = None + self.type: QAPISchemaType # set during check() self.optional = optional self.features = features or [] From patchwork Wed Apr 24 08:16:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641506 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A3CACC4345F for ; Wed, 24 Apr 2024 08:19:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpE-0001JO-VQ; Wed, 24 Apr 2024 04:17:56 -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 1rzXof-0000O8-2Y for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXob-0006MQ-8X for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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=t3fOLBPh4dp0SE7cx7ahHukai3oDTh0ff6lrbxzjRlE=; b=CYS6Ncy40/ArwPeOFXhBVgQgHx0C5lelRAcT3ucH0sai2oGj02kTwCrfirzT7WkBjAb1iR +hxdUIYa5v3BKekzX/si7BCRRyM52Unn1A0p5FUBS3Hn63mZhmwen37ek/QnZuajRMlrNC ioFpVUAh1zIH4PidJ5i7NOO0Btap+Kg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-269-6jC6NP3HNqmgaB8QyiUHwQ-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: 6jC6NP3HNqmgaB8QyiUHwQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2CD5980D678; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0D0E52166B31; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id D7EAE21E65D8; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 07/25] qapi/schema: declare type for QAPISchemaArrayType.element_type Date: Wed, 24 Apr 2024 10:16:52 +0200 Message-ID: <20240424081710.2907748-8-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow A QAPISchemaArrayType's element type gets resolved only during .check(). We have QAPISchemaArrayType.__init__() initialize self.element_type = None, and .check() assign the actual type. Using .element_type before .check() is wrong, and hopefully crashes due to the value being None. Works. However, it makes for awkward typing. With .element_type: Optional[QAPISchemaType], mypy is of course unable to see that it's None before .check(), and a QAPISchemaType after. To help it over the hump, we'd have to assert self.element_type is not None before all the (valid) uses. The assertion catches invalid uses, but only at run time; mypy can't flag them. Instead, declare .element_type in .__init__() as QAPISchemaType *without* initializing it. Using .element_type before .check() now certainly crashes, which is an improvement. Mypy still can't flag invalid uses, but that's okay. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-8-armbru@redhat.com> --- scripts/qapi/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 307f8af01a..48f157fb91 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -381,7 +381,7 @@ def __init__(self, name, info, element_type): super().__init__(name, info, None) assert isinstance(element_type, str) self._element_type_name = element_type - self.element_type = None + self.element_type: QAPISchemaType def need_has_if_optional(self): # When FOO is an array, we still need has_FOO to distinguish From patchwork Wed Apr 24 08:16:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641524 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6BD6DC4345F for ; Wed, 24 Apr 2024 08:21:06 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpF-0001NS-NE; Wed, 24 Apr 2024 04:17:57 -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 1rzXof-0000Ok-GF for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17: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 1rzXob-0006N5-NQ for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946637; 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=lBJCFbjf3roQdO9+j3YUS7y1SwDDMCx19PhFNSbCPrw=; b=HoOj8JgFUARQLr6yGULqxZdBtvclYPA7wUAacz6Zb7VHXXbc3yj+dbU1sMRXr9RsvPuvP2 69RcnkoDr78/fue7IZ2ZSIuka/XRWG4kJLh7EnHbJyrNFbJo+jsWSNaIE0rJ2cCUiCzAQr HJ5ndzda59MngRnOw7pujvgnbFDgoMA= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-602-qNo9diBuO2SNx0ldUSpflg-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: qNo9diBuO2SNx0ldUSpflg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2D5C43806278; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0E50D1C060D0; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id DAC3621E65DE; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 08/25] qapi/schema: make c_type() and json_type() abstract methods Date: Wed, 24 Apr 2024 10:16:53 +0200 Message-ID: <20240424081710.2907748-9-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow These methods should always return a str, it's only the default abstract implementation that doesn't. They can be marked "abstract", which requires subclasses to override the method with the proper return type. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-9-armbru@redhat.com> --- scripts/qapi/schema.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 48f157fb91..0b01c841ff 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -16,6 +16,7 @@ # TODO catching name collisions in generated code would be nice +from abc import ABC, abstractmethod from collections import OrderedDict import os import re @@ -245,9 +246,10 @@ def visit(self, visitor): visitor.visit_include(self._sub_module.name, self.info) -class QAPISchemaType(QAPISchemaDefinition): +class QAPISchemaType(QAPISchemaDefinition, ABC): # Return the C type for common use. # For the types we commonly box, this is a pointer type. + @abstractmethod def c_type(self): pass @@ -259,6 +261,7 @@ def c_param_type(self): def c_unboxed_type(self): return self.c_type() + @abstractmethod def json_type(self): pass From patchwork Wed Apr 24 08:16:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641496 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2DCC0C10F15 for ; Wed, 24 Apr 2024 08:17:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXoe-0000NE-8j; Wed, 24 Apr 2024 04:17:20 -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 1rzXoc-0000Lq-Jb for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17: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 1rzXoZ-0006M0-Uw for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946635; 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=ISyh3RRXd2jvQFg0Yb6P52AqbwlJikH4TBpkFzkZ6Bw=; b=K7bzwXODiIQD8DCrwxpaQnOPkCPoFzTvgJ3V5uNDbdAlxJ3gKU93ZYloZRLIj8bi/6bRG+ WWtePe+1DJHfQMMTn44TBqQiP0s6WTVPbWomdYQ7+qQhQEtmrWmoFcawoHEtSl9h3RCBXP b/BuJL4h5pg/MZBOaEXE+homfNGwUHs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-151-90MCLKojM6SQbGbkQPAtUw-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: 90MCLKojM6SQbGbkQPAtUw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2C08F1011A14; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0CCC020128F3; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id DDBE521E65E1; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 09/25] qapi/schema: adjust type narrowing for mypy's benefit Date: Wed, 24 Apr 2024 10:16:54 +0200 Message-ID: <20240424081710.2907748-10-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow We already take care to perform some type narrowing for arg_type and ret_type, but not in a way where mypy can utilize the result once we add type hints, e.g.: qapi/schema.py:833: error: Incompatible types in assignment (expression has type "QAPISchemaType", variable has type "Optional[QAPISchemaObjectType]") [assignment] qapi/schema.py:893: error: Incompatible types in assignment (expression has type "QAPISchemaType", variable has type "Optional[QAPISchemaObjectType]") [assignment] A simple change to use a temporary variable helps the medicine go down. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-10-armbru@redhat.com> --- scripts/qapi/schema.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 0b01c841ff..e44802369d 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -843,13 +843,14 @@ def __init__(self, name, info, doc, ifcond, features, def check(self, schema): super().check(schema) if self._arg_type_name: - self.arg_type = schema.resolve_type( + arg_type = schema.resolve_type( self._arg_type_name, self.info, "command's 'data'") - if not isinstance(self.arg_type, QAPISchemaObjectType): + if not isinstance(arg_type, QAPISchemaObjectType): raise QAPISemError( self.info, "command's 'data' cannot take %s" - % self.arg_type.describe()) + % arg_type.describe()) + self.arg_type = arg_type if self.arg_type.variants and not self.boxed: raise QAPISemError( self.info, @@ -866,8 +867,8 @@ def check(self, schema): if self.name not in self.info.pragma.command_returns_exceptions: typ = self.ret_type if isinstance(typ, QAPISchemaArrayType): - typ = self.ret_type.element_type assert typ + typ = typ.element_type if not isinstance(typ, QAPISchemaObjectType): raise QAPISemError( self.info, @@ -903,13 +904,14 @@ def __init__(self, name, info, doc, ifcond, features, arg_type, boxed): def check(self, schema): super().check(schema) if self._arg_type_name: - self.arg_type = schema.resolve_type( + typ = schema.resolve_type( self._arg_type_name, self.info, "event's 'data'") - if not isinstance(self.arg_type, QAPISchemaObjectType): + if not isinstance(typ, QAPISchemaObjectType): raise QAPISemError( self.info, "event's 'data' cannot take %s" - % self.arg_type.describe()) + % typ.describe()) + self.arg_type = typ if self.arg_type.variants and not self.boxed: raise QAPISemError( self.info, From patchwork Wed Apr 24 08:16:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641529 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6DCA7C10F16 for ; Wed, 24 Apr 2024 08:22:53 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXp8-0000x2-5R; Wed, 24 Apr 2024 04:17: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 1rzXog-0000P7-6J for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:29 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXoc-0006NG-As for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946637; 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=/JA+E7+oxIQSq7gmDuExt2uAvYWnC5AlpRpdAm/hA4Q=; b=NMd+phVZS/yULyXi6GyxM/CsF/egedvc9Mb/8huFb+h7P9A4XANYVigaTOTBxd5HMLAxe1 W71U6JIBU/po4dMdnr/lAOwjZt22FzYj0SP0jQ9LTLnmyknfQVH4ZNFCPqUqpJZp3oVSXS Z3EsLxb7vvf0YuE22cm3Fy000QxDDRY= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-151-sHszDX_aPsuAVDnmoWw3jA-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: sHszDX_aPsuAVDnmoWw3jA-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2D6983C108C1; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0D88140C5C2; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id E0A1C21EE971; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 10/25] qapi/schema: add type narrowing to lookup_type() Date: Wed, 24 Apr 2024 10:16:55 +0200 Message-ID: <20240424081710.2907748-11-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow This function is a bit hard to type as-is; mypy needs some assertions to assist with the type narrowing. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-11-armbru@redhat.com> --- scripts/qapi/schema.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index e44802369d..1034825415 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -989,7 +989,9 @@ def lookup_entity(self, name, typ=None): return ent def lookup_type(self, name): - return self.lookup_entity(name, QAPISchemaType) + typ = self.lookup_entity(name, QAPISchemaType) + assert typ is None or isinstance(typ, QAPISchemaType) + return typ def resolve_type(self, name, info, what): typ = self.lookup_type(name) From patchwork Wed Apr 24 08:16:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641511 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 337B3C07E8E for ; Wed, 24 Apr 2024 08:19:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpH-0001VU-Sj; Wed, 24 Apr 2024 04:17:59 -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 1rzXod-0000MW-KO for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -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 1rzXoa-0006M4-CN for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946635; 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=Z1f9N5gj8dDzD4ofeRluY0Zm4ewm4jdZorGX3BtmJLI=; b=NhKzOmhO3ZN3Sa1vao3Vh7Zwuj2yy+Gzb9u6VpIdLf7Q2bKhpkjRjtcJi4xFtG8dA9eeOV /3tJFgydqQ/faetw8hczWVX9F6bAT9G61+TiVPmXh9ZU226BWv6VS5qfrtmN1cqpJGwXN4 rNmx2sDfFi0+Ei0HY8FI/VLRcZQ0KxQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-601-N9ZFeA_GPqufiKqkGLaxDg-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: N9ZFeA_GPqufiKqkGLaxDg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2C722834FBA; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0CE5A20296D2; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id E3A4E21D49C0; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 11/25] qapi/schema: assert resolve_type has 'info' and 'what' args on error Date: Wed, 24 Apr 2024 10:16:56 +0200 Message-ID: <20240424081710.2907748-12-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.4 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow resolve_type() is generally used to resolve configuration-provided type names into type objects, and generally requires valid 'info' and 'what' parameters. In some cases, such as with QAPISchemaArrayType.check(), resolve_type may be used to resolve built-in types and as such will not have an 'info' argument, but also must not fail in this scenario. Use an assertion to sate mypy that we will indeed have 'info' and 'what' parameters for the error pathway in resolve_type. Note: there are only three callsites to resolve_type at present where "info" is perceived by mypy to be possibly None: 1) QAPISchemaArrayType.check() 2) QAPISchemaObjectTypeMember.check() 3) QAPISchemaEvent.check() Of those three, only the first actually ever passes None; the other two are limited by their base class initializers which accept info=None, but neither subclass actually use a None value in practice, currently. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-12-armbru@redhat.com> --- scripts/qapi/schema.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 1034825415..0ef9b3398a 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -996,6 +996,7 @@ def lookup_type(self, name): def resolve_type(self, name, info, what): typ = self.lookup_type(name) if not typ: + assert info and what # built-in types must not fail lookup if callable(what): what = what(info) raise QAPISemError( From patchwork Wed Apr 24 08:16:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641505 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E513CC4345F for ; Wed, 24 Apr 2024 08:18:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpB-0001Fw-Rp; Wed, 24 Apr 2024 04:17:53 -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 1rzXod-0000Mz-TS for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXoa-0006MS-SE for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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+msAICXsvjcDlthJmm3X7WQUPEXlBOV+/3EZ10XoiM=; b=dCHc+Ozx8bRj9i8w5Q854vH3iH+Hijc69CKjWVVTrgjaSYP7cfiqwVwbp/gvleDtx0XXkM PurH27+dxkBezMPPS4JyF0DgKo78eYK2NzrTPkHguF2SRw8ORdBh1pjdh0ztO50yTlBrJt paIly2Gdx2ccjNaVfZS9oziJMKOadUY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-552-lAg7zbtUOSa4vAk3pS8S9A-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: lAg7zbtUOSa4vAk3pS8S9A-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2D151810BDC; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0D9CDC13FA3; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id E688021D49C2; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 12/25] qapi: Assert built-in types exist Date: Wed, 24 Apr 2024 10:16:57 +0200 Message-ID: <20240424081710.2907748-13-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org QAPISchema.lookup_type('FOO') returns a QAPISchemaType when type 'FOO' exists, else None. It won't return None for built-in types like 'int'. Since mypy can't see that, it'll complain that we assign the Optional[QAPISchemaType] returned by .lookup_type() to QAPISchemaType variables. Add assertions to help it over the hump. Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-13-armbru@redhat.com> Reviewed-by: John Snow --- scripts/qapi/introspect.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 67c7d89aae..4679b1bc2c 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -227,10 +227,14 @@ def _use_type(self, typ: QAPISchemaType) -> str: # Map the various integer types to plain int if typ.json_type() == 'int': - typ = self._schema.lookup_type('int') + type_int = self._schema.lookup_type('int') + assert type_int + typ = type_int elif (isinstance(typ, QAPISchemaArrayType) and typ.element_type.json_type() == 'int'): - typ = self._schema.lookup_type('intList') + type_intList = self._schema.lookup_type('intList') + assert type_intList + typ = type_intList # Add type to work queue if new if typ not in self._used_types: self._used_types.append(typ) From patchwork Wed Apr 24 08:16:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641498 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E4891C4345F for ; Wed, 24 Apr 2024 08:17:51 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXp2-0000hP-Uu; Wed, 24 Apr 2024 04:17:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXoc-0000Lk-Fj for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:18 -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 1rzXoZ-0006M2-Tv for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946635; 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=hOZho5WJyQsPeB2oDADvKDq4Lh1DY5xRk8EOyqA9dC0=; b=SUPkp/MVflOIF7EIH3avJ8L1Z0zt/92zSXQqnu1m2CSwYsslqHiYUxEjVohHWtxZEkT9gn SymVlYJHLSrFwM8MypiPLnLxLcdE6cZmfKQU91j1BEN4Ib0IydUsJU8MH84k6WgLs+oLaO UrjZwWlr1417m+Z1s5UeZFlH07TafU8= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-226--LQbqst9MNy31GFS2szkNg-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: -LQbqst9MNy31GFS2szkNg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2EFB129ABA18; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0CA541121313; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id E995521D49C4; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 13/25] qapi/schema: fix QAPISchemaArrayType.check's call to resolve_type Date: Wed, 24 Apr 2024 10:16:58 +0200 Message-ID: <20240424081710.2907748-14-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Adjust the expression at the callsite to work around mypy's weak type introspection that believes this expression can resolve to QAPISourceInfo; it cannot. (Fundamentally: self.info only resolves to false in a boolean expression when it is None; therefore this expression may only ever produce Optional[str]. mypy does not know that 'info', when it is a QAPISourceInfo object, cannot ever be false.) Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-14-armbru@redhat.com> --- scripts/qapi/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 0ef9b3398a..087c6e9366 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -395,7 +395,7 @@ def check(self, schema): super().check(schema) self.element_type = schema.resolve_type( self._element_type_name, self.info, - self.info and self.info.defn_meta) + self.info.defn_meta if self.info else None) assert not isinstance(self.element_type, QAPISchemaArrayType) def set_module(self, schema): From patchwork Wed Apr 24 08:16:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641501 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 03A1CC4345F for ; Wed, 24 Apr 2024 08:18:23 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXoz-0000QZ-4K; Wed, 24 Apr 2024 04:17:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXoc-0000MI-Py for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXoa-0006ME-AN for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946635; 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=E7WcKDggn/0k8j89J15HIGYRNmBWqaoKRSQCgDhMsgw=; b=WZcQ4KXerqyWr6R3Orfm0ppn4982nRMEAm0fUNwhKcQQS+aMpqf5WgXHrTEuPtAfIEhYFN tclUVFZvkqlpfLw1BZyfCHP2U7hsA6KDVXDVR6BsyIBqKC89zjd7xIb86aAzo9WlQOT9Dr AaEf/WJE4GVLhgBTBqVjhhk9KZy5Vp4= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-602-t-ZTRB0iPPKLDMgF2koD3Q-1; Wed, 24 Apr 2024 04:17:13 -0400 X-MC-Unique: t-ZTRB0iPPKLDMgF2koD3Q-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 635C429ABA1C; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 441011C0666A; Wed, 24 Apr 2024 08:17:13 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id EC80621D49C6; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 14/25] qapi/schema: assert info is present when necessary Date: Wed, 24 Apr 2024 10:16:59 +0200 Message-ID: <20240424081710.2907748-15-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow QAPISchemaInfo arguments can often be None because built-in definitions don't have such information. The type hint can only be Optional[QAPISchemaInfo] then. But, mypy gets upset about all the places where we exploit that it can't actually be None there. Add assertions that will help mypy over the hump, to enable adding type hints in a forthcoming commit. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-15-armbru@redhat.com> --- scripts/qapi/schema.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 087c6e9366..173e27d9e2 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -751,6 +751,7 @@ def describe(self, info): else: assert False + assert info is not None if defined_in != info.defn_name: return "%s '%s' of %s '%s'" % (role, self.name, meta, defined_in) return "%s '%s'" % (role, self.name) @@ -841,6 +842,7 @@ def __init__(self, name, info, doc, ifcond, features, self.coroutine = coroutine def check(self, schema): + assert self.info is not None super().check(schema) if self._arg_type_name: arg_type = schema.resolve_type( From patchwork Wed Apr 24 08:17:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641526 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9D76DC4345F for ; Wed, 24 Apr 2024 08:22:46 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXp7-0000q4-2y; Wed, 24 Apr 2024 04:17: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 1rzXog-0000PF-RU for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:29 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXoc-0006NV-Qe for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946637; 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=P3ebJxgqtKeNEuqmgXox1NIEsc+toRKBUwjJZbh3UfE=; b=FEKSJl0nKLxk+4t2zxb+pS6FotsUUT3e1t8Eh4lTamxsEOsDGerfwVea70w91GA9jBdCOx mvAFYz6i7eERjQTQh7wfVQ47YwCQsh/km+I5F+vHoEToGHO1fh4qgtPMOcHwG2vCec12ed 5pVmnVGw1QrX/LagO9PmKZg1S6RxuFs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-659-FSKkXLflMeGMaEMCrvWEfg-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: FSKkXLflMeGMaEMCrvWEfg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5CFE718065AE; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3CF5049F1F; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id EF4E321D49C8; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 15/25] qapi/schema: add _check_complete flag Date: Wed, 24 Apr 2024 10:17:00 +0200 Message-ID: <20240424081710.2907748-16-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Instead of using the None value for the members field, use a dedicated flag to detect recursive misconfigurations. This is intended to assist with subsequent patches that seek to remove the "None" value from the members field (which can never hold that value after the final call to check()) in order to simplify the static typing of that field; avoiding the need of assertions littered at many callsites to eliminate the possibility of the None value. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-16-armbru@redhat.com> --- scripts/qapi/schema.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 173e27d9e2..2c3de72ae6 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -450,12 +450,13 @@ def __init__(self, name, info, doc, ifcond, features, self.local_members = local_members self.variants = variants self.members = None + self._check_complete = False def check(self, schema): # This calls another type T's .check() exactly when the C # struct emitted by gen_object() contains that T's C struct # (pointers don't count). - if self.members is not None: + if self._check_complete: # A previous .check() completed: nothing to do return if self._checked: @@ -464,7 +465,7 @@ def check(self, schema): "object %s contains itself" % self.name) super().check(schema) - assert self._checked and self.members is None + assert self._checked and not self._check_complete seen = OrderedDict() if self._base_name: @@ -487,7 +488,8 @@ def check(self, schema): self.variants.check(schema, seen) self.variants.check_clash(self.info, seen) - self.members = members # mark completed + self.members = members + self._check_complete = True # mark completed # Check that the members of this type do not cause duplicate JSON members, # and update seen to track the members seen so far. Report any errors From patchwork Wed Apr 24 08:17:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641500 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 02AA1C4345F for ; Wed, 24 Apr 2024 08:18:10 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXp9-00012G-7w; Wed, 24 Apr 2024 04:17:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXog-0000PE-QK for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:29 -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 1rzXoc-0006NM-FU for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946637; 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=Z99NS76qH48U3Rq6MrfJtlvHgLpyxgol+XqPiEz7v00=; b=BPI1wMs0EeLnjMj7UF+ZsO77KhOqR4xl6nbP8dvRTfWBzDC+P+NxyNJydXKoZtnkFErpI3 xu8BRDCs2A5PeJSKa8mZZ3JWhejtFeAM0FkQqUHsseofqyQNImULOuaBoACXSlzhfStPhh T8ZXQEuoMpW93SMlwopoJYgGixLUC8k= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-76-UeF7BMbnONSB0s-vzti1sA-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: UeF7BMbnONSB0s-vzti1sA-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5DDAF1011351; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3D107400059; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id F21C521D49CA; Wed, 24 Apr 2024 10:17:10 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 16/25] qapi/schema: Don't initialize "members" with `None` Date: Wed, 24 Apr 2024 10:17:01 +0200 Message-ID: <20240424081710.2907748-17-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Declare, but don't initialize the "members" field with type List[QAPISchemaObjectTypeMember]. This simplifies the typing from what would otherwise be Optional[List[T]] to merely List[T]. This removes the need to add assertions to several callsites that this value is not None - which it never will be after the delayed initialization in check() anyway. The type declaration without initialization trick will cause accidental uses of this field prior to full initialization to raise an AttributeError. (Note that it is valid to have an empty members list, see the internal q_empty object as an example. For this reason, we cannot use the empty list as a replacement test for full initialization and instead rely on the _checked/_check_complete fields.) Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-17-armbru@redhat.com> --- scripts/qapi/schema.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 2c3de72ae6..74b0d7b007 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -20,7 +20,7 @@ from collections import OrderedDict import os import re -from typing import List, Optional +from typing import List, Optional, cast from .common import ( POINTER_SUFFIX, @@ -449,7 +449,7 @@ def __init__(self, name, info, doc, ifcond, features, self.base = None self.local_members = local_members self.variants = variants - self.members = None + self.members: List[QAPISchemaObjectTypeMember] self._check_complete = False def check(self, schema): @@ -482,7 +482,11 @@ def check(self, schema): for m in self.local_members: m.check(schema) m.check_clash(self.info, seen) - members = seen.values() + + # self.check_clash() works in terms of the supertype, but + # self.members is declared List[QAPISchemaObjectTypeMember]. + # Cast down to the subtype. + members = cast(List[QAPISchemaObjectTypeMember], list(seen.values())) if self.variants: self.variants.check(schema, seen) @@ -515,11 +519,9 @@ def is_implicit(self): return self.name.startswith('q_') def is_empty(self): - assert self.members is not None return not self.members and not self.variants def has_conditional_members(self): - assert self.members is not None return any(m.ifcond.is_present() for m in self.members) def c_name(self): From patchwork Wed Apr 24 08:17:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641507 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 43CC7C07E8E for ; Wed, 24 Apr 2024 08:19:09 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpB-0001Do-6B; Wed, 24 Apr 2024 04:17:53 -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 1rzXop-0000QQ-EH for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:37 -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 1rzXod-0006Nw-3K for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946638; 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=gMIv6q+prrBk6e30Kr2pIDbigWp/9Due2EgluZCmYQw=; b=f844NV0Rtb3i9IvOpoZBZOqeHDQ5XAEZ9IJH9/vI39jt0LHECuaYoE6hYRkykjc3Fx6bao RzlNLELYI+OJ7N7kmAH0+8yKAA4/AGz4SWyMxLBV18yBFrlitxqXne+nd29m4iN0kq6dbZ 79A1HVX82wEMhMqVeDy4tXJm/gHBlPQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-357-3-Y_l7oRPzi-MXk37sglQg-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: 3-Y_l7oRPzi-MXk37sglQg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9A61C10113E5; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7B1241121312; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 00C6721D49CC; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 17/25] qapi/schema: fix typing for QAPISchemaVariants.tag_member Date: Wed, 24 Apr 2024 10:17:02 +0200 Message-ID: <20240424081710.2907748-18-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow There are two related changes here: (1) We need to perform type narrowing for resolving the type of tag_member during check(), and (2) tag_member is a delayed initialization field, but we can hide it behind a property that raises an Exception if it's called too early. This simplifies the typing in quite a few places and avoids needing to assert that the "tag_member is not None" at a dozen callsites, which can be confusing and suggest the wrong thing to a drive-by contributor. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-18-armbru@redhat.com> --- scripts/qapi/schema.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 74b0d7b007..9c138badb0 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -627,25 +627,39 @@ def __init__(self, tag_name, info, tag_member, variants): assert isinstance(v, QAPISchemaVariant) self._tag_name = tag_name self.info = info - self.tag_member = tag_member + self._tag_member: Optional[QAPISchemaObjectTypeMember] = tag_member self.variants = variants + @property + def tag_member(self) -> 'QAPISchemaObjectTypeMember': + if self._tag_member is None: + raise RuntimeError( + "QAPISchemaVariants has no tag_member property until " + "after check() has been run." + ) + return self._tag_member + def set_defined_in(self, name): for v in self.variants: v.set_defined_in(name) def check(self, schema, seen): if self._tag_name: # union - self.tag_member = seen.get(c_name(self._tag_name)) + # We need to narrow the member type: + tmp = seen.get(c_name(self._tag_name)) + assert tmp is None or isinstance(tmp, QAPISchemaObjectTypeMember) + self._tag_member = tmp + base = "'base'" # Pointing to the base type when not implicit would be # nice, but we don't know it here - if not self.tag_member or self._tag_name != self.tag_member.name: + if not self._tag_member or self._tag_name != self._tag_member.name: raise QAPISemError( self.info, "discriminator '%s' is not a member of %s" % (self._tag_name, base)) # Here we do: + assert self.tag_member.defined_in base_type = schema.lookup_type(self.tag_member.defined_in) assert base_type if not base_type.is_implicit(): @@ -666,11 +680,13 @@ def check(self, schema, seen): "discriminator member '%s' of %s must not be conditional" % (self._tag_name, base)) else: # alternate + assert self._tag_member assert isinstance(self.tag_member.type, QAPISchemaEnumType) assert not self.tag_member.optional assert not self.tag_member.ifcond.is_present() if self._tag_name: # union # branches that are not explicitly covered get an empty type + assert self.tag_member.defined_in cases = {v.name for v in self.variants} for m in self.tag_member.type.members: if m.name not in cases: From patchwork Wed Apr 24 08:17:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641499 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 34FE8C4345F for ; Wed, 24 Apr 2024 08:18:06 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpC-0001Hw-Vw; Wed, 24 Apr 2024 04:17:55 -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 1rzXoe-0000ND-4u for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:20 -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 1rzXob-0006Mc-6m for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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=+suyJ9CEZ6z16G7+I6EJL+Is0+sEmcxtUSXVBuJKC80=; b=eFEIPrLW1MNlHtutX3wbD/X+t1SFo1G4rrmKkr4BXtB8fxLAFmZAboiwCU3+ZhSI1gl96k DI0Tjk4R/Tz37qTLDuW5z4EPwRv3tknPvOt9kzoBw//tNG2I3ITp66cxuD9hLNO6Q3c3xR ZZkU64vrODQIeYWDFMAT5pQTWDy0AHc= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-76-kwONCa-6Nm6iHkMU-aYSoQ-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: kwONCa-6Nm6iHkMU-aYSoQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5E2F629AC019; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3D3903543A; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 0390021D49D0; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 18/25] qapi/schema: assert inner type of QAPISchemaVariants in check_clash() Date: Wed, 24 Apr 2024 10:17:03 +0200 Message-ID: <20240424081710.2907748-19-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow QAPISchemaVariant's "variants" field is typed as List[QAPISchemaVariant], where the typing for QAPISchemaVariant allows its type field to be any QAPISchemaType. However, QAPISchemaVariant expects that all of its variants contain the narrower QAPISchemaObjectType. This relationship is enforced at runtime in QAPISchemaVariants.check(). This relationship is not embedded in the type system though, so QAPISchemaVariants.check_clash() needs to re-assert this property in order to call QAPISchemaVariant.type.check_clash(). Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-19-armbru@redhat.com> --- scripts/qapi/schema.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 9c138badb0..177bfa0d11 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -716,7 +716,10 @@ def check(self, schema, seen): def check_clash(self, info, seen): for v in self.variants: # Reset seen map for each variant, since qapi names from one - # branch do not affect another branch + # branch do not affect another branch. + # + # v.type's typing is enforced in check() above. + assert isinstance(v.type, QAPISchemaObjectType) v.type.check_clash(info, dict(seen)) From patchwork Wed Apr 24 08:17:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641513 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5890FC4345F for ; Wed, 24 Apr 2024 08:20:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpH-0001VR-T4; Wed, 24 Apr 2024 04:17:59 -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 1rzXof-0000Of-C1 for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXob-0006Mt-Ha for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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=90UWvPU4M74myGXrwLPAD5ftuRBynt2DVOF1/XUYENg=; b=eXbHRTowf4kxltwtmyQKhi1A7CNRXgycekZFGk7nWbiIgUZTuyEnAmHsVNCoYeJvIcQ1bY pplbVFU3mUL/D7HzNU662rwaYmacgaYAHFOCrvyC/xXyuRHG2Ho+AlNT3QBwRjUA/BON2y fCIDwqcTh2xif7Q0KOEVqEjqaGIg2s0= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-345-0xsswfttOx2DPuKbG7yJrg-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: 0xsswfttOx2DPuKbG7yJrg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5CEE6812C50; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3CF2549102; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 0668C21D49E4; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 19/25] qapi/parser: demote QAPIExpression to Dict[str, Any] Date: Wed, 24 Apr 2024 10:17:04 +0200 Message-ID: <20240424081710.2907748-20-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Dict[str, object] is a stricter type, but with the way that code is currently arranged, it is infeasible to enforce this strictness. In particular, although expr.py's entire raison d'être is normalization and type-checking of QAPI Expressions, that type information is not "remembered" in any meaningful way by mypy because each individual expression is not downcast to a specific expression type that holds all the details of each expression's unique form. As a result, all of the code in schema.py that deals with actually creating type-safe specialized structures has no guarantee (myopically) that the data it is being passed is correct. There are two ways to solve this: (1) Re-assert that the incoming data is in the shape we expect it to be, or (2) Disable type checking for this data. (1) is appealing to my sense of strictness, but I gotta concede that it is asinine to re-check the shape of a QAPIExpression in schema.py when expr.py has just completed that work at length. The duplication of code and the nightmare thought of needing to update both locations if and when we change the shape of these structures makes me extremely reluctant to go down this route. (2) allows us the chance to miss updating types in the case that types are updated in expr.py, but it *is* an awful lot simpler and, importantly, gets us closer to type checking schema.py *at all*. Something is better than nothing, I'd argue. So, do the simpler dumber thing and worry about future strictness improvements later. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-20-armbru@redhat.com> --- scripts/qapi/parser.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index ec4ebef4e3..2f3c704fa2 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -19,6 +19,7 @@ import re from typing import ( TYPE_CHECKING, + Any, Dict, List, Mapping, @@ -43,7 +44,7 @@ _ExprValue = Union[List[object], Dict[str, object], str, bool] -class QAPIExpression(Dict[str, object]): +class QAPIExpression(Dict[str, Any]): # pylint: disable=too-few-public-methods def __init__(self, data: Mapping[str, object], From patchwork Wed Apr 24 08:17:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641528 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 59916C10F15 for ; Wed, 24 Apr 2024 08:22:53 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpA-00016L-TP; Wed, 24 Apr 2024 04:17:52 -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 1rzXoj-0000PL-C3 for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:29 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXod-0006OB-GN for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946638; 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=NhEL6w/MFAQxFANlXcE7j5u/TREVl1BHvL8lYonuZ5Y=; b=XH77JRgT689sTOVsCizSn/YLaJbBdvd+ip9AnrDHy/y6CxpqT8FgUDv5dTmreGW7b+G7Vx 6alxbvxVFBQu2KT7H9iWvJPUBcHdRiF1rl/E9EUS0wMaDMddA5I8tQXfIAo0jEwo8f0f12 T3qS2kwm1zNC//djvYx25uDTBWltRec= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-171-CFZC1VqANqyu-rKjuiEhyw-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: CFZC1VqANqyu-rKjuiEhyw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5DD05800CA2; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3CCCF1121312; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 091A121D49E6; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 20/25] qapi/parser.py: assert member.info is present in connect_member Date: Wed, 24 Apr 2024 10:17:05 +0200 Message-ID: <20240424081710.2907748-21-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.3 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-21-armbru@redhat.com> --- scripts/qapi/parser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index 2f3c704fa2..7b13a583ac 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -707,6 +707,7 @@ def append_line(self, line: str) -> None: def connect_member(self, member: 'QAPISchemaMember') -> None: if member.name not in self.args: + assert member.info if self.symbol not in member.info.pragma.documentation_exceptions: raise QAPISemError(member.info, "%s '%s' lacks documentation" From patchwork Wed Apr 24 08:17:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641503 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E4380C4345F for ; Wed, 24 Apr 2024 08:18:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpE-0001Iz-C1; Wed, 24 Apr 2024 04:17:56 -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 1rzXop-0000QS-FP for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:38 -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 1rzXoe-0006OR-22 for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946639; 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=Twx6rYhKBMninBR1Egpve+KOz7kD0IGuLCYI25/u94o=; b=fzMJYsHpI4Kf4UNwLcEAzD56dCQVCQ+bnHm7BdHOK1ZnqZb/fzl0RpGDKk3AFSKL+WwmBK 6cnSnYN/2Q+weRqIttW0rzHvEgLZGh206PN2gWfwFXGT0WsQbzmw5K/IGkA3mjX7OuQSxP bkhBqm+15mrI/kqpII6BmeNoaxuKsbA= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-516-MnoJ_xtPPoeQy8udgVRqCg-1; Wed, 24 Apr 2024 04:17:15 -0400 X-MC-Unique: MnoJ_xtPPoeQy8udgVRqCg-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id C46C929AC01E; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3CDBE492BC7; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 0C77621D49E8; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 21/25] qapi/schema: add type hints Date: Wed, 24 Apr 2024 10:17:06 +0200 Message-ID: <20240424081710.2907748-22-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow This patch only adds type hints, which aren't utilized at runtime and don't change the behavior of this module in any way. In a scant few locations, type hints are removed where no longer necessary due to inference power from typing all of the rest of creation; and any type hints that no longer need string quotes are changed. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-22-armbru@redhat.com> --- scripts/qapi/schema.py | 568 ++++++++++++++++++++++++++++------------- 1 file changed, 396 insertions(+), 172 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 177bfa0d11..ef4d6a7def 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -16,11 +16,21 @@ # TODO catching name collisions in generated code would be nice +from __future__ import annotations + from abc import ABC, abstractmethod from collections import OrderedDict import os import re -from typing import List, Optional, cast +from typing import ( + Any, + Callable, + Dict, + List, + Optional, + Union, + cast, +) from .common import ( POINTER_SUFFIX, @@ -32,26 +42,30 @@ ) from .error import QAPIError, QAPISemError, QAPISourceError from .expr import check_exprs -from .parser import QAPIExpression, QAPISchemaParser +from .parser import QAPIDoc, QAPIExpression, QAPISchemaParser +from .source import QAPISourceInfo class QAPISchemaIfCond: - def __init__(self, ifcond=None): + def __init__( + self, + ifcond: Optional[Union[str, Dict[str, object]]] = None, + ) -> None: self.ifcond = ifcond - def _cgen(self): + def _cgen(self) -> str: return cgen_ifcond(self.ifcond) - def gen_if(self): + def gen_if(self) -> str: return gen_if(self._cgen()) - def gen_endif(self): + def gen_endif(self) -> str: return gen_endif(self._cgen()) - def docgen(self): + def docgen(self) -> str: return docgen_ifcond(self.ifcond) - def is_present(self): + def is_present(self) -> bool: return bool(self.ifcond) @@ -62,8 +76,8 @@ class QAPISchemaEntity: This is either a directive, such as include, or a definition. The latter uses sub-class `QAPISchemaDefinition`. """ - def __init__(self, info): - self._module = None + def __init__(self, info: Optional[QAPISourceInfo]): + self._module: Optional[QAPISchemaModule] = None # For explicitly defined entities, info points to the (explicit) # definition. For builtins (and their arrays), info is None. # For implicitly defined entities, info points to a place that @@ -72,34 +86,43 @@ def __init__(self, info): self.info = info self._checked = False - def __repr__(self): + def __repr__(self) -> str: return "<%s at 0x%x>" % (type(self).__name__, id(self)) - def check(self, schema): + def check(self, schema: QAPISchema) -> None: # pylint: disable=unused-argument self._checked = True - def connect_doc(self, doc=None): + def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None: pass - def _set_module(self, schema, info): + def _set_module( + self, schema: QAPISchema, info: Optional[QAPISourceInfo] + ) -> None: assert self._checked fname = info.fname if info else QAPISchemaModule.BUILTIN_MODULE_NAME self._module = schema.module_by_fname(fname) self._module.add_entity(self) - def set_module(self, schema): + def set_module(self, schema: QAPISchema) -> None: self._set_module(schema, self.info) - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: # pylint: disable=unused-argument assert self._checked class QAPISchemaDefinition(QAPISchemaEntity): - meta: Optional[str] = None + meta: str - def __init__(self, name: str, info, doc, ifcond=None, features=None): + def __init__( + self, + name: str, + info: Optional[QAPISourceInfo], + doc: Optional[QAPIDoc], + ifcond: Optional[QAPISchemaIfCond] = None, + features: Optional[List[QAPISchemaFeature]] = None, + ): assert isinstance(name, str) super().__init__(info) for f in features or []: @@ -110,21 +133,21 @@ def __init__(self, name: str, info, doc, ifcond=None, features=None): self._ifcond = ifcond or QAPISchemaIfCond() self.features = features or [] - def __repr__(self): + def __repr__(self) -> str: return "<%s:%s at 0x%x>" % (type(self).__name__, self.name, id(self)) - def c_name(self): + def c_name(self) -> str: return c_name(self.name) - def check(self, schema): + def check(self, schema: QAPISchema) -> None: assert not self._checked super().check(schema) - seen = {} + seen: Dict[str, QAPISchemaMember] = {} for f in self.features: f.check_clash(self.info, seen) - def connect_doc(self, doc=None): + def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None: super().connect_doc(doc) doc = doc or self.doc if doc: @@ -132,62 +155,120 @@ def connect_doc(self, doc=None): doc.connect_feature(f) @property - def ifcond(self): + def ifcond(self) -> QAPISchemaIfCond: assert self._checked return self._ifcond - def is_implicit(self): + def is_implicit(self) -> bool: return not self.info - def describe(self): + def describe(self) -> str: assert self.meta return "%s '%s'" % (self.meta, self.name) class QAPISchemaVisitor: - def visit_begin(self, schema): + def visit_begin(self, schema: QAPISchema) -> None: pass - def visit_end(self): + def visit_end(self) -> None: pass - def visit_module(self, name): + def visit_module(self, name: str) -> None: pass - def visit_needed(self, entity): + def visit_needed(self, entity: QAPISchemaEntity) -> bool: # pylint: disable=unused-argument # Default to visiting everything return True - def visit_include(self, name, info): + def visit_include(self, name: str, info: Optional[QAPISourceInfo]) -> None: pass - def visit_builtin_type(self, name, info, json_type): + def visit_builtin_type( + self, name: str, info: Optional[QAPISourceInfo], json_type: str + ) -> None: pass - def visit_enum_type(self, name, info, ifcond, features, members, prefix): + def visit_enum_type( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + members: List[QAPISchemaEnumMember], + prefix: Optional[str], + ) -> None: pass - def visit_array_type(self, name, info, ifcond, element_type): + def visit_array_type( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: QAPISchemaIfCond, + element_type: QAPISchemaType, + ) -> None: pass - def visit_object_type(self, name, info, ifcond, features, - base, members, variants): + def visit_object_type( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + base: Optional[QAPISchemaObjectType], + members: List[QAPISchemaObjectTypeMember], + variants: Optional[QAPISchemaVariants], + ) -> None: pass - def visit_object_type_flat(self, name, info, ifcond, features, - members, variants): + def visit_object_type_flat( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + members: List[QAPISchemaObjectTypeMember], + variants: Optional[QAPISchemaVariants], + ) -> None: pass - def visit_alternate_type(self, name, info, ifcond, features, variants): + def visit_alternate_type( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + variants: QAPISchemaVariants, + ) -> None: pass - def visit_command(self, name, info, ifcond, features, - arg_type, ret_type, gen, success_response, boxed, - allow_oob, allow_preconfig, coroutine): + def visit_command( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + arg_type: Optional[QAPISchemaObjectType], + ret_type: Optional[QAPISchemaType], + gen: bool, + success_response: bool, + boxed: bool, + allow_oob: bool, + allow_preconfig: bool, + coroutine: bool, + ) -> None: pass - def visit_event(self, name, info, ifcond, features, arg_type, boxed): + def visit_event( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + arg_type: Optional[QAPISchemaObjectType], + boxed: bool, + ) -> None: pass @@ -195,9 +276,9 @@ class QAPISchemaModule: BUILTIN_MODULE_NAME = './builtin' - def __init__(self, name): + def __init__(self, name: str): self.name = name - self._entity_list = [] + self._entity_list: List[QAPISchemaEntity] = [] @staticmethod def is_system_module(name: str) -> bool: @@ -226,10 +307,10 @@ def is_builtin_module(cls, name: str) -> bool: """ return name == cls.BUILTIN_MODULE_NAME - def add_entity(self, ent): + def add_entity(self, ent: QAPISchemaEntity) -> None: self._entity_list.append(ent) - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: visitor.visit_module(self.name) for entity in self._entity_list: if visitor.visit_needed(entity): @@ -237,11 +318,11 @@ def visit(self, visitor): class QAPISchemaInclude(QAPISchemaEntity): - def __init__(self, sub_module, info): + def __init__(self, sub_module: QAPISchemaModule, info: QAPISourceInfo): super().__init__(info) self._sub_module = sub_module - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_include(self._sub_module.name, self.info) @@ -250,22 +331,22 @@ class QAPISchemaType(QAPISchemaDefinition, ABC): # Return the C type for common use. # For the types we commonly box, this is a pointer type. @abstractmethod - def c_type(self): + def c_type(self) -> str: pass # Return the C type to be used in a parameter list. - def c_param_type(self): + def c_param_type(self) -> str: return self.c_type() # Return the C type to be used where we suppress boxing. - def c_unboxed_type(self): + def c_unboxed_type(self) -> str: return self.c_type() @abstractmethod - def json_type(self): + def json_type(self) -> str: pass - def alternate_qtype(self): + def alternate_qtype(self) -> Optional[str]: json2qtype = { 'null': 'QTYPE_QNULL', 'string': 'QTYPE_QSTRING', @@ -277,17 +358,17 @@ def alternate_qtype(self): } return json2qtype.get(self.json_type()) - def doc_type(self): + def doc_type(self) -> Optional[str]: if self.is_implicit(): return None return self.name - def need_has_if_optional(self): + def need_has_if_optional(self) -> bool: # When FOO is a pointer, has_FOO == !!FOO, i.e. has_FOO is redundant. # Except for arrays; see QAPISchemaArrayType.need_has_if_optional(). return not self.c_type().endswith(POINTER_SUFFIX) - def check(self, schema): + def check(self, schema: QAPISchema) -> None: super().check(schema) for feat in self.features: if feat.is_special(): @@ -295,7 +376,7 @@ def check(self, schema): self.info, f"feature '{feat.name}' is not supported for types") - def describe(self): + def describe(self) -> str: assert self.meta return "%s type '%s'" % (self.meta, self.name) @@ -303,7 +384,7 @@ def describe(self): class QAPISchemaBuiltinType(QAPISchemaType): meta = 'built-in' - def __init__(self, name, json_type, c_type): + def __init__(self, name: str, json_type: str, c_type: str): super().__init__(name, None, None) assert not c_type or isinstance(c_type, str) assert json_type in ('string', 'number', 'int', 'boolean', 'null', @@ -311,24 +392,24 @@ def __init__(self, name, json_type, c_type): self._json_type_name = json_type self._c_type_name = c_type - def c_name(self): + def c_name(self) -> str: return self.name - def c_type(self): + def c_type(self) -> str: return self._c_type_name - def c_param_type(self): + def c_param_type(self) -> str: if self.name == 'str': return 'const ' + self._c_type_name return self._c_type_name - def json_type(self): + def json_type(self) -> str: return self._json_type_name - def doc_type(self): + def doc_type(self) -> str: return self.json_type() - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_builtin_type(self.name, self.info, self.json_type()) @@ -336,7 +417,16 @@ def visit(self, visitor): class QAPISchemaEnumType(QAPISchemaType): meta = 'enum' - def __init__(self, name, info, doc, ifcond, features, members, prefix): + def __init__( + self, + name: str, + info: Optional[QAPISourceInfo], + doc: Optional[QAPIDoc], + ifcond: Optional[QAPISchemaIfCond], + features: Optional[List[QAPISchemaFeature]], + members: List[QAPISchemaEnumMember], + prefix: Optional[str], + ): super().__init__(name, info, doc, ifcond, features) for m in members: assert isinstance(m, QAPISchemaEnumMember) @@ -345,32 +435,32 @@ def __init__(self, name, info, doc, ifcond, features, members, prefix): self.members = members self.prefix = prefix - def check(self, schema): + def check(self, schema: QAPISchema) -> None: super().check(schema) - seen = {} + seen: Dict[str, QAPISchemaMember] = {} for m in self.members: m.check_clash(self.info, seen) - def connect_doc(self, doc=None): + def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None: super().connect_doc(doc) doc = doc or self.doc for m in self.members: m.connect_doc(doc) - def is_implicit(self): + def is_implicit(self) -> bool: # See QAPISchema._def_predefineds() return self.name == 'QType' - def c_type(self): + def c_type(self) -> str: return c_name(self.name) - def member_names(self): + def member_names(self) -> List[str]: return [m.name for m in self.members] - def json_type(self): + def json_type(self) -> str: return 'string' - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_enum_type( self.name, self.info, self.ifcond, self.features, @@ -380,60 +470,71 @@ def visit(self, visitor): class QAPISchemaArrayType(QAPISchemaType): meta = 'array' - def __init__(self, name, info, element_type): + def __init__( + self, name: str, info: Optional[QAPISourceInfo], element_type: str + ): super().__init__(name, info, None) assert isinstance(element_type, str) self._element_type_name = element_type self.element_type: QAPISchemaType - def need_has_if_optional(self): + def need_has_if_optional(self) -> bool: # When FOO is an array, we still need has_FOO to distinguish # absent (!has_FOO) from present and empty (has_FOO && !FOO). return True - def check(self, schema): + def check(self, schema: QAPISchema) -> None: super().check(schema) self.element_type = schema.resolve_type( self._element_type_name, self.info, self.info.defn_meta if self.info else None) assert not isinstance(self.element_type, QAPISchemaArrayType) - def set_module(self, schema): + def set_module(self, schema: QAPISchema) -> None: self._set_module(schema, self.element_type.info) @property - def ifcond(self): + def ifcond(self) -> QAPISchemaIfCond: assert self._checked return self.element_type.ifcond - def is_implicit(self): + def is_implicit(self) -> bool: return True - def c_type(self): + def c_type(self) -> str: return c_name(self.name) + POINTER_SUFFIX - def json_type(self): + def json_type(self) -> str: return 'array' - def doc_type(self): + def doc_type(self) -> Optional[str]: elt_doc_type = self.element_type.doc_type() if not elt_doc_type: return None return 'array of ' + elt_doc_type - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_array_type(self.name, self.info, self.ifcond, self.element_type) - def describe(self): + def describe(self) -> str: assert self.meta return "%s type ['%s']" % (self.meta, self._element_type_name) class QAPISchemaObjectType(QAPISchemaType): - def __init__(self, name, info, doc, ifcond, features, - base, local_members, variants): + def __init__( + self, + name: str, + info: Optional[QAPISourceInfo], + doc: Optional[QAPIDoc], + ifcond: Optional[QAPISchemaIfCond], + features: Optional[List[QAPISchemaFeature]], + base: Optional[str], + local_members: List[QAPISchemaObjectTypeMember], + variants: Optional[QAPISchemaVariants], + ): # struct has local_members, optional base, and no variants # union has base, variants, and no local_members super().__init__(name, info, doc, ifcond, features) @@ -452,7 +553,7 @@ def __init__(self, name, info, doc, ifcond, features, self.members: List[QAPISchemaObjectTypeMember] self._check_complete = False - def check(self, schema): + def check(self, schema: QAPISchema) -> None: # This calls another type T's .check() exactly when the C # struct emitted by gen_object() contains that T's C struct # (pointers don't count). @@ -498,14 +599,18 @@ def check(self, schema): # Check that the members of this type do not cause duplicate JSON members, # and update seen to track the members seen so far. Report any errors # on behalf of info, which is not necessarily self.info - def check_clash(self, info, seen): + def check_clash( + self, + info: Optional[QAPISourceInfo], + seen: Dict[str, QAPISchemaMember], + ) -> None: assert self._checked for m in self.members: m.check_clash(info, seen) if self.variants: self.variants.check_clash(info, seen) - def connect_doc(self, doc=None): + def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None: super().connect_doc(doc) doc = doc or self.doc if self.base and self.base.is_implicit(): @@ -513,32 +618,32 @@ def connect_doc(self, doc=None): for m in self.local_members: m.connect_doc(doc) - def is_implicit(self): + def is_implicit(self) -> bool: # See QAPISchema._make_implicit_object_type(), as well as # _def_predefineds() return self.name.startswith('q_') - def is_empty(self): + def is_empty(self) -> bool: return not self.members and not self.variants - def has_conditional_members(self): + def has_conditional_members(self) -> bool: return any(m.ifcond.is_present() for m in self.members) - def c_name(self): + def c_name(self) -> str: assert self.name != 'q_empty' return super().c_name() - def c_type(self): + def c_type(self) -> str: assert not self.is_implicit() return c_name(self.name) + POINTER_SUFFIX - def c_unboxed_type(self): + def c_unboxed_type(self) -> str: return c_name(self.name) - def json_type(self): + def json_type(self) -> str: return 'object' - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_object_type( self.name, self.info, self.ifcond, self.features, @@ -551,7 +656,15 @@ def visit(self, visitor): class QAPISchemaAlternateType(QAPISchemaType): meta = 'alternate' - def __init__(self, name, info, doc, ifcond, features, variants): + def __init__( + self, + name: str, + info: QAPISourceInfo, + doc: Optional[QAPIDoc], + ifcond: Optional[QAPISchemaIfCond], + features: List[QAPISchemaFeature], + variants: QAPISchemaVariants, + ): super().__init__(name, info, doc, ifcond, features) assert isinstance(variants, QAPISchemaVariants) assert variants.tag_member @@ -559,7 +672,7 @@ def __init__(self, name, info, doc, ifcond, features, variants): variants.tag_member.set_defined_in(self.name) self.variants = variants - def check(self, schema): + def check(self, schema: QAPISchema) -> None: super().check(schema) self.variants.tag_member.check(schema) # Not calling self.variants.check_clash(), because there's nothing @@ -567,8 +680,8 @@ def check(self, schema): self.variants.check(schema, {}) # Alternate branch names have no relation to the tag enum values; # so we have to check for potential name collisions ourselves. - seen = {} - types_seen = {} + seen: Dict[str, QAPISchemaMember] = {} + types_seen: Dict[str, str] = {} for v in self.variants.variants: v.check_clash(self.info, seen) qtype = v.type.alternate_qtype() @@ -597,26 +710,32 @@ def check(self, schema): % (v.describe(self.info), types_seen[qt])) types_seen[qt] = v.name - def connect_doc(self, doc=None): + def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None: super().connect_doc(doc) doc = doc or self.doc for v in self.variants.variants: v.connect_doc(doc) - def c_type(self): + def c_type(self) -> str: return c_name(self.name) + POINTER_SUFFIX - def json_type(self): + def json_type(self) -> str: return 'value' - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_alternate_type( self.name, self.info, self.ifcond, self.features, self.variants) class QAPISchemaVariants: - def __init__(self, tag_name, info, tag_member, variants): + def __init__( + self, + tag_name: Optional[str], + info: QAPISourceInfo, + tag_member: Optional[QAPISchemaObjectTypeMember], + variants: List[QAPISchemaVariant], + ): # Unions pass tag_name but not tag_member. # Alternates pass tag_member but not tag_name. # After check(), tag_member is always set. @@ -627,11 +746,11 @@ def __init__(self, tag_name, info, tag_member, variants): assert isinstance(v, QAPISchemaVariant) self._tag_name = tag_name self.info = info - self._tag_member: Optional[QAPISchemaObjectTypeMember] = tag_member + self._tag_member = tag_member self.variants = variants @property - def tag_member(self) -> 'QAPISchemaObjectTypeMember': + def tag_member(self) -> QAPISchemaObjectTypeMember: if self._tag_member is None: raise RuntimeError( "QAPISchemaVariants has no tag_member property until " @@ -639,11 +758,13 @@ def tag_member(self) -> 'QAPISchemaObjectTypeMember': ) return self._tag_member - def set_defined_in(self, name): + def set_defined_in(self, name: str) -> None: for v in self.variants: v.set_defined_in(name) - def check(self, schema, seen): + def check( + self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember] + ) -> None: if self._tag_name: # union # We need to narrow the member type: tmp = seen.get(c_name(self._tag_name)) @@ -713,7 +834,11 @@ def check(self, schema, seen): % (v.describe(self.info), v.type.describe())) v.type.check(schema) - def check_clash(self, info, seen): + def check_clash( + self, + info: Optional[QAPISourceInfo], + seen: Dict[str, QAPISchemaMember], + ) -> None: for v in self.variants: # Reset seen map for each variant, since qapi names from one # branch do not affect another branch. @@ -727,18 +852,27 @@ class QAPISchemaMember: """ Represents object members, enum members and features """ role = 'member' - def __init__(self, name, info, ifcond=None): + def __init__( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: Optional[QAPISchemaIfCond] = None, + ): assert isinstance(name, str) self.name = name self.info = info self.ifcond = ifcond or QAPISchemaIfCond() - self.defined_in = None + self.defined_in: Optional[str] = None - def set_defined_in(self, name): + def set_defined_in(self, name: str) -> None: assert not self.defined_in self.defined_in = name - def check_clash(self, info, seen): + def check_clash( + self, + info: Optional[QAPISourceInfo], + seen: Dict[str, QAPISchemaMember], + ) -> None: cname = c_name(self.name) if cname in seen: raise QAPISemError( @@ -747,11 +881,11 @@ def check_clash(self, info, seen): % (self.describe(info), seen[cname].describe(info))) seen[cname] = self - def connect_doc(self, doc): + def connect_doc(self, doc: Optional[QAPIDoc]) -> None: if doc: doc.connect_member(self) - def describe(self, info): + def describe(self, info: Optional[QAPISourceInfo]) -> str: role = self.role meta = 'type' defined_in = self.defined_in @@ -783,14 +917,20 @@ def describe(self, info): class QAPISchemaEnumMember(QAPISchemaMember): role = 'value' - def __init__(self, name, info, ifcond=None, features=None): + def __init__( + self, + name: str, + info: Optional[QAPISourceInfo], + ifcond: Optional[QAPISchemaIfCond] = None, + features: Optional[List[QAPISchemaFeature]] = None, + ): super().__init__(name, info, ifcond) for f in features or []: assert isinstance(f, QAPISchemaFeature) f.set_defined_in(name) self.features = features or [] - def connect_doc(self, doc): + def connect_doc(self, doc: Optional[QAPIDoc]) -> None: super().connect_doc(doc) if doc: for f in self.features: @@ -800,12 +940,20 @@ def connect_doc(self, doc): class QAPISchemaFeature(QAPISchemaMember): role = 'feature' - def is_special(self): + def is_special(self) -> bool: return self.name in ('deprecated', 'unstable') class QAPISchemaObjectTypeMember(QAPISchemaMember): - def __init__(self, name, info, typ, optional, ifcond=None, features=None): + def __init__( + self, + name: str, + info: QAPISourceInfo, + typ: str, + optional: bool, + ifcond: Optional[QAPISchemaIfCond] = None, + features: Optional[List[QAPISchemaFeature]] = None, + ): super().__init__(name, info, ifcond) assert isinstance(typ, str) assert isinstance(optional, bool) @@ -817,19 +965,19 @@ def __init__(self, name, info, typ, optional, ifcond=None, features=None): self.optional = optional self.features = features or [] - def need_has(self): + def need_has(self) -> bool: assert self.type return self.optional and self.type.need_has_if_optional() - def check(self, schema): + def check(self, schema: QAPISchema) -> None: assert self.defined_in self.type = schema.resolve_type(self._type_name, self.info, self.describe) - seen = {} + seen: Dict[str, QAPISchemaMember] = {} for f in self.features: f.check_clash(self.info, seen) - def connect_doc(self, doc): + def connect_doc(self, doc: Optional[QAPIDoc]) -> None: super().connect_doc(doc) if doc: for f in self.features: @@ -839,24 +987,42 @@ def connect_doc(self, doc): class QAPISchemaVariant(QAPISchemaObjectTypeMember): role = 'branch' - def __init__(self, name, info, typ, ifcond=None): + def __init__( + self, + name: str, + info: QAPISourceInfo, + typ: str, + ifcond: QAPISchemaIfCond, + ): super().__init__(name, info, typ, False, ifcond) class QAPISchemaCommand(QAPISchemaDefinition): meta = 'command' - def __init__(self, name, info, doc, ifcond, features, - arg_type, ret_type, - gen, success_response, boxed, allow_oob, allow_preconfig, - coroutine): + def __init__( + self, + name: str, + info: QAPISourceInfo, + doc: Optional[QAPIDoc], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + arg_type: Optional[str], + ret_type: Optional[str], + gen: bool, + success_response: bool, + boxed: bool, + allow_oob: bool, + allow_preconfig: bool, + coroutine: bool, + ): super().__init__(name, info, doc, ifcond, features) assert not arg_type or isinstance(arg_type, str) assert not ret_type or isinstance(ret_type, str) self._arg_type_name = arg_type - self.arg_type = None + self.arg_type: Optional[QAPISchemaObjectType] = None self._ret_type_name = ret_type - self.ret_type = None + self.ret_type: Optional[QAPISchemaType] = None self.gen = gen self.success_response = success_response self.boxed = boxed @@ -864,7 +1030,7 @@ def __init__(self, name, info, doc, ifcond, features, self.allow_preconfig = allow_preconfig self.coroutine = coroutine - def check(self, schema): + def check(self, schema: QAPISchema) -> None: assert self.info is not None super().check(schema) if self._arg_type_name: @@ -900,14 +1066,14 @@ def check(self, schema): "command's 'returns' cannot take %s" % self.ret_type.describe()) - def connect_doc(self, doc=None): + def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None: super().connect_doc(doc) doc = doc or self.doc if doc: if self.arg_type and self.arg_type.is_implicit(): self.arg_type.connect_doc(doc) - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_command( self.name, self.info, self.ifcond, self.features, @@ -919,14 +1085,23 @@ def visit(self, visitor): class QAPISchemaEvent(QAPISchemaDefinition): meta = 'event' - def __init__(self, name, info, doc, ifcond, features, arg_type, boxed): + def __init__( + self, + name: str, + info: QAPISourceInfo, + doc: Optional[QAPIDoc], + ifcond: QAPISchemaIfCond, + features: List[QAPISchemaFeature], + arg_type: Optional[str], + boxed: bool, + ): super().__init__(name, info, doc, ifcond, features) assert not arg_type or isinstance(arg_type, str) self._arg_type_name = arg_type - self.arg_type = None + self.arg_type: Optional[QAPISchemaObjectType] = None self.boxed = boxed - def check(self, schema): + def check(self, schema: QAPISchema) -> None: super().check(schema) if self._arg_type_name: typ = schema.resolve_type( @@ -948,14 +1123,14 @@ def check(self, schema): self.info, "conditional event arguments require 'boxed': true") - def connect_doc(self, doc=None): + def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None: super().connect_doc(doc) doc = doc or self.doc if doc: if self.arg_type and self.arg_type.is_implicit(): self.arg_type.connect_doc(doc) - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: super().visit(visitor) visitor.visit_event( self.name, self.info, self.ifcond, self.features, @@ -963,7 +1138,7 @@ def visit(self, visitor): class QAPISchema: - def __init__(self, fname): + def __init__(self, fname: str): self.fname = fname try: @@ -975,9 +1150,9 @@ def __init__(self, fname): exprs = check_exprs(parser.exprs) self.docs = parser.docs - self._entity_list = [] - self._entity_dict = {} - self._module_dict = OrderedDict() + self._entity_list: List[QAPISchemaEntity] = [] + self._entity_dict: Dict[str, QAPISchemaDefinition] = {} + self._module_dict: Dict[str, QAPISchemaModule] = OrderedDict() self._schema_dir = os.path.dirname(fname) self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME) self._make_module(fname) @@ -987,10 +1162,10 @@ def __init__(self, fname): self._def_exprs(exprs) self.check() - def _def_entity(self, ent): + def _def_entity(self, ent: QAPISchemaEntity) -> None: self._entity_list.append(ent) - def _def_definition(self, defn): + def _def_definition(self, defn: QAPISchemaDefinition) -> None: # Only the predefined types are allowed to not have info assert defn.info or self._predefining self._def_entity(defn) @@ -1007,18 +1182,27 @@ def _def_definition(self, defn): defn.info, "%s is already defined" % other_defn.describe()) self._entity_dict[defn.name] = defn - def lookup_entity(self, name, typ=None): + def lookup_entity( + self, + name: str, + typ: Optional[type] = None, + ) -> Optional[QAPISchemaDefinition]: ent = self._entity_dict.get(name) if typ and not isinstance(ent, typ): return None return ent - def lookup_type(self, name): + def lookup_type(self, name: str) -> Optional[QAPISchemaType]: typ = self.lookup_entity(name, QAPISchemaType) assert typ is None or isinstance(typ, QAPISchemaType) return typ - def resolve_type(self, name, info, what): + def resolve_type( + self, + name: str, + info: Optional[QAPISourceInfo], + what: Union[None, str, Callable[[QAPISourceInfo], str]], + ) -> QAPISchemaType: typ = self.lookup_type(name) if not typ: assert info and what # built-in types must not fail lookup @@ -1033,23 +1217,25 @@ def _module_name(self, fname: str) -> str: return fname return os.path.relpath(fname, self._schema_dir) - def _make_module(self, fname): + def _make_module(self, fname: str) -> QAPISchemaModule: name = self._module_name(fname) if name not in self._module_dict: self._module_dict[name] = QAPISchemaModule(name) return self._module_dict[name] - def module_by_fname(self, fname): + def module_by_fname(self, fname: str) -> QAPISchemaModule: name = self._module_name(fname) return self._module_dict[name] - def _def_include(self, expr: QAPIExpression): + def _def_include(self, expr: QAPIExpression) -> None: include = expr['include'] assert expr.doc is None self._def_entity( QAPISchemaInclude(self._make_module(include), expr.info)) - def _def_builtin_type(self, name, json_type, c_type): + def _def_builtin_type( + self, name: str, json_type: str, c_type: str + ) -> None: self._def_definition(QAPISchemaBuiltinType(name, json_type, c_type)) # Instantiating only the arrays that are actually used would # be nice, but we can't as long as their generated code @@ -1057,7 +1243,7 @@ def _def_builtin_type(self, name, json_type, c_type): # schema. self._make_array_type(name, None) - def _def_predefineds(self): + def _def_predefineds(self) -> None: for t in [('str', 'string', 'char' + POINTER_SUFFIX), ('number', 'number', 'double'), ('int', 'int', 'int64_t'), @@ -1086,31 +1272,52 @@ def _def_predefineds(self): self._def_definition(QAPISchemaEnumType( 'QType', None, None, None, None, qtype_values, 'QTYPE')) - def _make_features(self, features, info): + def _make_features( + self, + features: Optional[List[Dict[str, Any]]], + info: Optional[QAPISourceInfo], + ) -> List[QAPISchemaFeature]: if features is None: return [] return [QAPISchemaFeature(f['name'], info, QAPISchemaIfCond(f.get('if'))) for f in features] - def _make_enum_member(self, name, ifcond, features, info): + def _make_enum_member( + self, + name: str, + ifcond: Optional[Union[str, Dict[str, Any]]], + features: Optional[List[Dict[str, Any]]], + info: Optional[QAPISourceInfo], + ) -> QAPISchemaEnumMember: return QAPISchemaEnumMember(name, info, QAPISchemaIfCond(ifcond), self._make_features(features, info)) - def _make_enum_members(self, values, info): + def _make_enum_members( + self, values: List[Dict[str, Any]], info: Optional[QAPISourceInfo] + ) -> List[QAPISchemaEnumMember]: return [self._make_enum_member(v['name'], v.get('if'), v.get('features'), info) for v in values] - def _make_array_type(self, element_type, info): + def _make_array_type( + self, element_type: str, info: Optional[QAPISourceInfo] + ) -> str: name = element_type + 'List' # reserved by check_defn_name_str() if not self.lookup_type(name): self._def_definition(QAPISchemaArrayType( name, info, element_type)) return name - def _make_implicit_object_type(self, name, info, ifcond, role, members): + def _make_implicit_object_type( + self, + name: str, + info: QAPISourceInfo, + ifcond: QAPISchemaIfCond, + role: str, + members: List[QAPISchemaObjectTypeMember], + ) -> Optional[str]: if not members: return None # See also QAPISchemaObjectTypeMember.describe() @@ -1126,7 +1333,7 @@ def _make_implicit_object_type(self, name, info, ifcond, role, members): name, info, None, ifcond, None, None, members, None)) return name - def _def_enum_type(self, expr: QAPIExpression): + def _def_enum_type(self, expr: QAPIExpression) -> None: name = expr['enum'] data = expr['data'] prefix = expr.get('prefix') @@ -1137,7 +1344,14 @@ def _def_enum_type(self, expr: QAPIExpression): name, info, expr.doc, ifcond, features, self._make_enum_members(data, info), prefix)) - def _make_member(self, name, typ, ifcond, features, info): + def _make_member( + self, + name: str, + typ: Union[List[str], str], + ifcond: QAPISchemaIfCond, + features: Optional[List[Dict[str, Any]]], + info: QAPISourceInfo, + ) -> QAPISchemaObjectTypeMember: optional = False if name.startswith('*'): name = name[1:] @@ -1148,13 +1362,17 @@ def _make_member(self, name, typ, ifcond, features, info): return QAPISchemaObjectTypeMember(name, info, typ, optional, ifcond, self._make_features(features, info)) - def _make_members(self, data, info): + def _make_members( + self, + data: Dict[str, Any], + info: QAPISourceInfo, + ) -> List[QAPISchemaObjectTypeMember]: return [self._make_member(key, value['type'], QAPISchemaIfCond(value.get('if')), value.get('features'), info) for (key, value) in data.items()] - def _def_struct_type(self, expr: QAPIExpression): + def _def_struct_type(self, expr: QAPIExpression) -> None: name = expr['struct'] base = expr.get('base') data = expr['data'] @@ -1166,13 +1384,19 @@ def _def_struct_type(self, expr: QAPIExpression): self._make_members(data, info), None)) - def _make_variant(self, case, typ, ifcond, info): + def _make_variant( + self, + case: str, + typ: str, + ifcond: QAPISchemaIfCond, + info: QAPISourceInfo, + ) -> QAPISchemaVariant: if isinstance(typ, list): assert len(typ) == 1 typ = self._make_array_type(typ[0], info) return QAPISchemaVariant(case, info, typ, ifcond) - def _def_union_type(self, expr: QAPIExpression): + def _def_union_type(self, expr: QAPIExpression) -> None: name = expr['union'] base = expr['base'] tag_name = expr['discriminator'] @@ -1197,7 +1421,7 @@ def _def_union_type(self, expr: QAPIExpression): QAPISchemaVariants( tag_name, info, None, variants))) - def _def_alternate_type(self, expr: QAPIExpression): + def _def_alternate_type(self, expr: QAPIExpression) -> None: name = expr['alternate'] data = expr['data'] assert isinstance(data, dict) @@ -1215,7 +1439,7 @@ def _def_alternate_type(self, expr: QAPIExpression): name, info, expr.doc, ifcond, features, QAPISchemaVariants(None, info, tag_member, variants))) - def _def_command(self, expr: QAPIExpression): + def _def_command(self, expr: QAPIExpression) -> None: name = expr['command'] data = expr.get('data') rets = expr.get('returns') @@ -1240,7 +1464,7 @@ def _def_command(self, expr: QAPIExpression): rets, gen, success_response, boxed, allow_oob, allow_preconfig, coroutine)) - def _def_event(self, expr: QAPIExpression): + def _def_event(self, expr: QAPIExpression) -> None: name = expr['event'] data = expr.get('data') boxed = expr.get('boxed', False) @@ -1254,7 +1478,7 @@ def _def_event(self, expr: QAPIExpression): self._def_definition(QAPISchemaEvent(name, info, expr.doc, ifcond, features, data, boxed)) - def _def_exprs(self, exprs): + def _def_exprs(self, exprs: List[QAPIExpression]) -> None: for expr in exprs: if 'enum' in expr: self._def_enum_type(expr) @@ -1273,7 +1497,7 @@ def _def_exprs(self, exprs): else: assert False - def check(self): + def check(self) -> None: for ent in self._entity_list: ent.check(self) ent.connect_doc() @@ -1282,7 +1506,7 @@ def check(self): for doc in self.docs: doc.check() - def visit(self, visitor): + def visit(self, visitor: QAPISchemaVisitor) -> None: visitor.visit_begin(self) for mod in self._module_dict.values(): mod.visit(visitor) From patchwork Wed Apr 24 08:17:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641510 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 62648C4345F for ; Wed, 24 Apr 2024 08:19:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXoo-0000QK-FE; Wed, 24 Apr 2024 04:17:30 -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 1rzXof-0000OC-5k for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXob-0006Mo-Gj for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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=Wz1zxirIKAizmFcsqM70mJlR0iniwwzgVCKiwzPR6tQ=; b=SshfFRpR8aS9Dw0Ppi8OxrVIkQWPbcjdTK+oFjHzUJe6YGfSscunnNaIVg61G+FoSrS7Lg P5Zg9dwB+70xpUBRovNhRkOZPvv5NbjO9WHKMei3ax45QnTJeD50/BgCn4l6XlX5FbY+9o 7W2SNbf8rSnTxXMxbtp+rjhwp764Y4Q= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-345-z6fcVgTTOgyFNgs_KQyo-A-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: z6fcVgTTOgyFNgs_KQyo-A-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5C47D8001B2; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3D08640C140B; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 0F43021F980F; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 22/25] qapi/schema: turn on mypy strictness Date: Wed, 24 Apr 2024 10:17:07 +0200 Message-ID: <20240424081710.2907748-23-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.2 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow This patch can be rolled in with the previous one once the series is ready for merge, but for work-in-progress' sake, it's separate here. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-23-armbru@redhat.com> --- scripts/qapi/mypy.ini | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/qapi/mypy.ini b/scripts/qapi/mypy.ini index 56e0dfb132..8109470a03 100644 --- a/scripts/qapi/mypy.ini +++ b/scripts/qapi/mypy.ini @@ -2,8 +2,3 @@ strict = True disallow_untyped_calls = False python_version = 3.8 - -[mypy-qapi.schema] -disallow_untyped_defs = False -disallow_incomplete_defs = False -check_untyped_defs = False From patchwork Wed Apr 24 08:17:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641527 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1DA5BC4345F for ; Wed, 24 Apr 2024 08:22:50 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpC-0001Go-7T; Wed, 24 Apr 2024 04:17: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 1rzXop-0000QR-Ek for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:38 -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 1rzXod-0006OE-Jh for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946639; 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=sW/1LPbGvCQulJkoaMsEee1B55s3T0QllG3s+V3Hx0M=; b=P+aqXrUbRZYNi6qDtgMrw70YC+LuGueGfsxf17KzVNE7t4LKhK69K380LMPnPNLKhECzzW qFJVcQUU/nBbefkta2EzTTimPIdyb8GbFNxLUWTK5YUeQiSiLIbrFTzbP1lJ6s9CAbyjA4 C82nc7WUm7oXRhqIGESwWRNq8sqsMA4= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-636-HGAFIeVtOeapZkPvD-Sswg-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: HGAFIeVtOeapZkPvD-Sswg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7625A3C108D3; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3CEE42166B34; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 11FF021F9811; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 23/25] qapi/schema: remove unnecessary asserts Date: Wed, 24 Apr 2024 10:17:08 +0200 Message-ID: <20240424081710.2907748-24-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: John Snow With strict typing enabled, these runtime statements aren't necessary anymore; we can prove them statically. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-24-armbru@redhat.com> --- scripts/qapi/schema.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index ef4d6a7def..e52930a48a 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -123,10 +123,8 @@ def __init__( ifcond: Optional[QAPISchemaIfCond] = None, features: Optional[List[QAPISchemaFeature]] = None, ): - assert isinstance(name, str) super().__init__(info) for f in features or []: - assert isinstance(f, QAPISchemaFeature) f.set_defined_in(name) self.name = name self.doc = doc @@ -163,7 +161,6 @@ def is_implicit(self) -> bool: return not self.info def describe(self) -> str: - assert self.meta return "%s '%s'" % (self.meta, self.name) @@ -377,7 +374,6 @@ def check(self, schema: QAPISchema) -> None: f"feature '{feat.name}' is not supported for types") def describe(self) -> str: - assert self.meta return "%s type '%s'" % (self.meta, self.name) @@ -386,7 +382,6 @@ class QAPISchemaBuiltinType(QAPISchemaType): def __init__(self, name: str, json_type: str, c_type: str): super().__init__(name, None, None) - assert not c_type or isinstance(c_type, str) assert json_type in ('string', 'number', 'int', 'boolean', 'null', 'value') self._json_type_name = json_type @@ -429,9 +424,7 @@ def __init__( ): super().__init__(name, info, doc, ifcond, features) for m in members: - assert isinstance(m, QAPISchemaEnumMember) m.set_defined_in(name) - assert prefix is None or isinstance(prefix, str) self.members = members self.prefix = prefix @@ -474,7 +467,6 @@ def __init__( self, name: str, info: Optional[QAPISourceInfo], element_type: str ): super().__init__(name, info, None) - assert isinstance(element_type, str) self._element_type_name = element_type self.element_type: QAPISchemaType @@ -519,7 +511,6 @@ def visit(self, visitor: QAPISchemaVisitor) -> None: self.element_type) def describe(self) -> str: - assert self.meta return "%s type ['%s']" % (self.meta, self._element_type_name) @@ -539,12 +530,9 @@ def __init__( # union has base, variants, and no local_members super().__init__(name, info, doc, ifcond, features) self.meta = 'union' if variants else 'struct' - assert base is None or isinstance(base, str) for m in local_members: - assert isinstance(m, QAPISchemaObjectTypeMember) m.set_defined_in(name) if variants is not None: - assert isinstance(variants, QAPISchemaVariants) variants.set_defined_in(name) self._base_name = base self.base = None @@ -666,7 +654,6 @@ def __init__( variants: QAPISchemaVariants, ): super().__init__(name, info, doc, ifcond, features) - assert isinstance(variants, QAPISchemaVariants) assert variants.tag_member variants.set_defined_in(name) variants.tag_member.set_defined_in(self.name) @@ -742,8 +729,6 @@ def __init__( assert bool(tag_member) != bool(tag_name) assert (isinstance(tag_name, str) or isinstance(tag_member, QAPISchemaObjectTypeMember)) - for v in variants: - assert isinstance(v, QAPISchemaVariant) self._tag_name = tag_name self.info = info self._tag_member = tag_member @@ -858,7 +843,6 @@ def __init__( info: Optional[QAPISourceInfo], ifcond: Optional[QAPISchemaIfCond] = None, ): - assert isinstance(name, str) self.name = name self.info = info self.ifcond = ifcond or QAPISchemaIfCond() @@ -926,7 +910,6 @@ def __init__( ): super().__init__(name, info, ifcond) for f in features or []: - assert isinstance(f, QAPISchemaFeature) f.set_defined_in(name) self.features = features or [] @@ -955,10 +938,7 @@ def __init__( features: Optional[List[QAPISchemaFeature]] = None, ): super().__init__(name, info, ifcond) - assert isinstance(typ, str) - assert isinstance(optional, bool) for f in features or []: - assert isinstance(f, QAPISchemaFeature) f.set_defined_in(name) self._type_name = typ self.type: QAPISchemaType # set during check() @@ -966,7 +946,6 @@ def __init__( self.features = features or [] def need_has(self) -> bool: - assert self.type return self.optional and self.type.need_has_if_optional() def check(self, schema: QAPISchema) -> None: @@ -1017,8 +996,6 @@ def __init__( coroutine: bool, ): super().__init__(name, info, doc, ifcond, features) - assert not arg_type or isinstance(arg_type, str) - assert not ret_type or isinstance(ret_type, str) self._arg_type_name = arg_type self.arg_type: Optional[QAPISchemaObjectType] = None self._ret_type_name = ret_type @@ -1058,7 +1035,6 @@ def check(self, schema: QAPISchema) -> None: if self.name not in self.info.pragma.command_returns_exceptions: typ = self.ret_type if isinstance(typ, QAPISchemaArrayType): - assert typ typ = typ.element_type if not isinstance(typ, QAPISchemaObjectType): raise QAPISemError( @@ -1096,7 +1072,6 @@ def __init__( boxed: bool, ): super().__init__(name, info, doc, ifcond, features) - assert not arg_type or isinstance(arg_type, str) self._arg_type_name = arg_type self.arg_type: Optional[QAPISchemaObjectType] = None self.boxed = boxed From patchwork Wed Apr 24 08:17:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641530 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 657F5C07E8E for ; Wed, 24 Apr 2024 08:23:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpI-0001Vc-10; Wed, 24 Apr 2024 04:18:00 -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 1rzXof-0000O7-1f for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rzXob-0006Mf-9K for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946636; 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=CDW0Xz9TlyAbEVZVLeFRsDcKqdQmawhWBp1iG9NppSk=; b=diFSu/Xdl6zAmvj0CLOxkRhDOZFQ7K9N/rws39wUyyjBKfbfzDx0Nlc+4/kwb95Dpry0DC Zt1+II8RKDKk7CRgso5zoWuOt9rkc0xUty8ZAIb+rrw4jki57CQLkKu7ygM+kI7/GP2UTG NE0EPFQn35yd5DKYEHAjEQoF3EDhc84= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-659-ljW-VVLsMQGvToo9B0fL4g-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: ljW-VVLsMQGvToo9B0fL4g-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5DE6F830E85; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3D02740C5C2; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 14F9721E6811; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , John Snow Subject: [PULL 24/25] qapi: Tighten check whether implicit object type already exists Date: Wed, 24 Apr 2024 10:17:09 +0200 Message-ID: <20240424081710.2907748-25-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.10 Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Entities with names starting with q_obj_ are implicit object types. Therefore, QAPISchema._make_implicit_object_type()'s .lookup_entity() can only return a QAPISchemaObjectType. Assert that. Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-25-armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: John Snow --- scripts/qapi/schema.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index e52930a48a..a6180f93c6 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -1297,8 +1297,9 @@ def _make_implicit_object_type( return None # See also QAPISchemaObjectTypeMember.describe() name = 'q_obj_%s-%s' % (name, role) - typ = self.lookup_entity(name, QAPISchemaObjectType) + typ = self.lookup_entity(name) if typ: + assert(isinstance(typ, QAPISchemaObjectType)) # The implicit object type has multiple users. This can # only be a duplicate definition, which will be flagged # later. From patchwork Wed Apr 24 08:17:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 13641508 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D3AB1C4345F for ; Wed, 24 Apr 2024 08:19:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rzXpD-0001ID-4z; Wed, 24 Apr 2024 04:17:55 -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 1rzXog-0000PC-Pw for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:29 -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 1rzXoc-0006NR-Gu for qemu-devel@nongnu.org; Wed, 24 Apr 2024 04:17:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713946637; 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=QcafE001xOcjxMIocmQop4ggl5SkBI7dDGkHJDJs+Ho=; b=Nf+wj000hqBIkynnrqjmVO3p2cC2HR1jqhV4i1lIkT2RUApam7sAX9qSiOSLtQnwwtHsOu IA+MZbnECtT+2cGu+tJZPSW/D74c5ybz4NXWrRlFPSQjAg+jvvv67B+reBbm0ppl9TmC0K KUSuqgUsA1TQw/Pr7y2CbfVCp62JbbY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-636-8yL8lh6AM4O4FmnGtMUYSg-1; Wed, 24 Apr 2024 04:17:14 -0400 X-MC-Unique: 8yL8lh6AM4O4FmnGtMUYSg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5D65A80253A; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.247]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3D391C15771; Wed, 24 Apr 2024 08:17:14 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 179D721F980D; Wed, 24 Apr 2024 10:17:11 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, John Snow Subject: [PULL 25/25] qapi: Dumb down QAPISchema.lookup_entity() Date: Wed, 24 Apr 2024 10:17:10 +0200 Message-ID: <20240424081710.2907748-26-armbru@redhat.com> In-Reply-To: <20240424081710.2907748-1-armbru@redhat.com> References: <20240424081710.2907748-1-armbru@redhat.com> MIME-Version: 1.0 Content-type: text/plain X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.8 Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.67, 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_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org QAPISchema.lookup_entity() takes an optional type argument, a subtype of QAPISchemaDefinition, and returns that type or None. Callers can use this to save themselves an isinstance() test. The only remaining user of this convenience feature is .lookup_type(). But we don't actually save anything anymore there: we still need the isinstance() to help mypy over the hump. Drop the .lookup_entity() argument, and adjust .lookup_type(). Signed-off-by: Markus Armbruster Message-ID: <20240315152301.3621858-26-armbru@redhat.com> Reviewed-by: John Snow [Commit message typo fixed] --- scripts/qapi/schema.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index a6180f93c6..5924947fc3 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -1157,20 +1157,14 @@ def _def_definition(self, defn: QAPISchemaDefinition) -> None: defn.info, "%s is already defined" % other_defn.describe()) self._entity_dict[defn.name] = defn - def lookup_entity( - self, - name: str, - typ: Optional[type] = None, - ) -> Optional[QAPISchemaDefinition]: - ent = self._entity_dict.get(name) - if typ and not isinstance(ent, typ): - return None - return ent + def lookup_entity(self,name: str) -> Optional[QAPISchemaEntity]: + return self._entity_dict.get(name) def lookup_type(self, name: str) -> Optional[QAPISchemaType]: - typ = self.lookup_entity(name, QAPISchemaType) - assert typ is None or isinstance(typ, QAPISchemaType) - return typ + typ = self.lookup_entity(name) + if isinstance(typ, QAPISchemaType): + return typ + return None def resolve_type( self,