aboutsummaryrefslogtreecommitdiff
path: root/scripts/qapi/schema.py
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2025-02-05 12:35:50 +0000
committerMarkus Armbruster <armbru@redhat.com>2025-02-10 15:45:04 +0100
commit2ebb09f34ffff152dda6d2b5d9a2348f3fefc6d3 (patch)
tree6aa65d06a207844348101396a1923c6d8fad6709 /scripts/qapi/schema.py
parentba27dccc04f16e143cbf59afec5402198d69be30 (diff)
downloadqemu-2ebb09f34ffff152dda6d2b5d9a2348f3fefc6d3.zip
qemu-2ebb09f34ffff152dda6d2b5d9a2348f3fefc6d3.tar.gz
qemu-2ebb09f34ffff152dda6d2b5d9a2348f3fefc6d3.tar.bz2
qapi: expose all schema features to code
This replaces use of the constants from the QapiSpecialFeatures enum, with constants from the auto-generate QapiFeatures enum in qapi-features.h The 'deprecated' and 'unstable' features still have a little bit of special handling, being force defined to be the 1st + 2nd features in the enum, regardless of whether they're used in the schema. This retains compatibility with common code that references the features via the QapiSpecialFeatures constants. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-ID: <20250205123550.2754387-5-berrange@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Imports tidied up with isort] Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'scripts/qapi/schema.py')
-rw-r--r--scripts/qapi/schema.py31
1 files changed, 30 insertions, 1 deletions
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index e97c978..7f70969 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -29,6 +29,7 @@ from typing import (
List,
Optional,
Union,
+ ValuesView,
cast,
)
@@ -933,8 +934,11 @@ class QAPISchemaEnumMember(QAPISchemaMember):
class QAPISchemaFeature(QAPISchemaMember):
role = 'feature'
+ # Features which are standardized across all schemas
+ SPECIAL_NAMES = ['deprecated', 'unstable']
+
def is_special(self) -> bool:
- return self.name in ('deprecated', 'unstable')
+ return self.name in QAPISchemaFeature.SPECIAL_NAMES
class QAPISchemaObjectTypeMember(QAPISchemaMember):
@@ -1138,6 +1142,16 @@ class QAPISchema:
self._entity_list: List[QAPISchemaEntity] = []
self._entity_dict: Dict[str, QAPISchemaDefinition] = {}
self._module_dict: Dict[str, QAPISchemaModule] = OrderedDict()
+ # NB, values in the dict will identify the first encountered
+ # usage of a named feature only
+ self._feature_dict: Dict[str, QAPISchemaFeature] = OrderedDict()
+
+ # All schemas get the names defined in the QapiSpecialFeature enum.
+ # Rely on dict iteration order matching insertion order so that
+ # the special names are emitted first when generating code.
+ for f in QAPISchemaFeature.SPECIAL_NAMES:
+ self._feature_dict[f] = QAPISchemaFeature(f, None)
+
self._schema_dir = os.path.dirname(fname)
self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME)
self._make_module(fname)
@@ -1147,6 +1161,9 @@ class QAPISchema:
self._def_exprs(exprs)
self.check()
+ def features(self) -> ValuesView[QAPISchemaFeature]:
+ return self._feature_dict.values()
+
def _def_entity(self, ent: QAPISchemaEntity) -> None:
self._entity_list.append(ent)
@@ -1258,6 +1275,12 @@ class QAPISchema:
) -> List[QAPISchemaFeature]:
if features is None:
return []
+
+ for f in features:
+ feat = QAPISchemaFeature(f['name'], info)
+ if feat.name not in self._feature_dict:
+ self._feature_dict[feat.name] = feat
+
return [QAPISchemaFeature(f['name'], info,
QAPISchemaIfCond(f.get('if')))
for f in features]
@@ -1485,6 +1508,12 @@ class QAPISchema:
for doc in self.docs:
doc.check()
+ features = list(self._feature_dict.values())
+ if len(features) > 64:
+ raise QAPISemError(
+ features[64].info,
+ "Maximum of 64 schema features is permitted")
+
def visit(self, visitor: QAPISchemaVisitor) -> None:
visitor.visit_begin(self)
for mod in self._module_dict.values():