diff options
author | Daniel P. Berrangé <berrange@redhat.com> | 2025-02-05 12:35:50 +0000 |
---|---|---|
committer | Markus Armbruster <armbru@redhat.com> | 2025-02-10 15:45:04 +0100 |
commit | 2ebb09f34ffff152dda6d2b5d9a2348f3fefc6d3 (patch) | |
tree | 6aa65d06a207844348101396a1923c6d8fad6709 /scripts/qapi/schema.py | |
parent | ba27dccc04f16e143cbf59afec5402198d69be30 (diff) | |
download | qemu-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.py | 31 |
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(): |