qapi/schema: declare type for QAPISchemaArrayType.element_type
authorJohn Snow <jsnow@redhat.com>
Fri, 15 Mar 2024 15:22:43 +0000 (16:22 +0100)
committerMarkus Armbruster <armbru@redhat.com>
Wed, 24 Apr 2024 08:03:54 +0000 (10:03 +0200)
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 <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20240315152301.3621858-8-armbru@redhat.com>

scripts/qapi/schema.py

index 307f8af01a955511572b87ba737e0af0c692070e..48f157fb915ce07e96a355f9aa1d109a032d80de 100644 (file)
@@ -381,7 +381,7 @@ class QAPISchemaArrayType(QAPISchemaType):
         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