[PATCH v4 2/5] qapi: Add feature flags to enum members
John Snow
jsnow at redhat.com
Tue Oct 26 20:48:56 UTC 2021
On Mon, Oct 25, 2021 at 12:24 AM Markus Armbruster <armbru at redhat.com>
wrote:
> This is quite similar to commit 84ab008687 "qapi: Add feature flags to
> struct members", only for enums instead of structs.
>
> Special feature flag 'deprecated' is silently ignored there. This is
> okay only because it will be implemented shortly.
>
> Signed-off-by: Markus Armbruster <armbru at redhat.com>
> Reviewed-by: Eric Blake <eblake at redhat.com>
>
Reviewed-by: John Snow <jsnow at redhat.com>
> ---
> docs/devel/qapi-code-gen.rst | 16 +++++++++-----
> qapi/compat.json | 2 ++
> qapi/introspect.json | 5 ++++-
> scripts/qapi/expr.py | 3 ++-
> scripts/qapi/introspect.py | 5 +++--
> scripts/qapi/schema.py | 22 +++++++++++++++++--
> tests/qapi-schema/doc-good.json | 5 ++++-
> tests/qapi-schema/doc-good.out | 3 +++
> tests/qapi-schema/doc-good.txt | 3 +++
> .../qapi-schema/enum-dict-member-unknown.err | 2 +-
> tests/qapi-schema/qapi-schema-test.json | 3 ++-
> tests/qapi-schema/qapi-schema-test.out | 1 +
> tests/qapi-schema/test-qapi.py | 1 +
> 13 files changed, 57 insertions(+), 14 deletions(-)
>
> diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
> index d267889d2c..4071c9074a 100644
> --- a/docs/devel/qapi-code-gen.rst
> +++ b/docs/devel/qapi-code-gen.rst
> @@ -200,7 +200,9 @@ Syntax::
> '*if': COND,
> '*features': FEATURES }
> ENUM-VALUE = STRING
> - | { 'name': STRING, '*if': COND }
> + | { 'name': STRING,
> + '*if': COND,
> + '*features': FEATURES }
>
> Member 'enum' names the enum type.
>
> @@ -706,8 +708,10 @@ QEMU shows a certain behaviour.
> Special features
> ~~~~~~~~~~~~~~~~
>
> -Feature "deprecated" marks a command, event, or struct member as
> -deprecated. It is not supported elsewhere so far.
> +Feature "deprecated" marks a command, event, enum value, or struct
> +member as deprecated. It is not supported elsewhere so far.
> +Interfaces so marked may be withdrawn in future releases in accordance
> +with QEMU's deprecation policy.
>
>
> Naming rules and reserved names
> @@ -1157,7 +1161,8 @@ and "variants".
>
> "members" is a JSON array describing the object's common members, if
> any. Each element is a JSON object with members "name" (the member's
> -name), "type" (the name of its type), and optionally "default". The
> +name), "type" (the name of its type), "features" (a JSON array of
> +feature strings), and "default". The latter two are optional. The
> member is optional if "default" is present. Currently, "default" can
> only have value null. Other values are reserved for future
> extensions. The "members" array is in no particular order; clients
> @@ -1234,7 +1239,8 @@ The SchemaInfo for an enumeration type has meta-type
> "enum" and
> variant member "members".
>
> "members" is a JSON array describing the enumeration values. Each
> -element is a JSON object with member "name" (the member's name). The
> +element is a JSON object with member "name" (the member's name), and
> +optionally "features" (a JSON array of feature strings). The
> "members" array is in no particular order; clients must search the
> entire array when learning whether a particular value is supported.
>
> diff --git a/qapi/compat.json b/qapi/compat.json
> index ae3afc22df..1d2b76f00c 100644
> --- a/qapi/compat.json
> +++ b/qapi/compat.json
> @@ -42,6 +42,8 @@
> # with feature 'deprecated'. We may want to extend it to cover
> # semantic aspects, CLI, and experimental features.
> #
> +# Limitation: not implemented for deprecated enumeration values.
> +#
> # @deprecated-input: how to handle deprecated input (default 'accept')
> # @deprecated-output: how to handle deprecated output (default 'accept')
> #
> diff --git a/qapi/introspect.json b/qapi/introspect.json
> index 9683e884f8..183148b2e9 100644
> --- a/qapi/introspect.json
> +++ b/qapi/introspect.json
> @@ -167,10 +167,13 @@
> #
> # @name: the member's name, as defined in the QAPI schema.
> #
> +# @features: names of features associated with the member, in no
> +# particular order.
> +#
> # Since: 6.2
> ##
> { 'struct': 'SchemaInfoEnumMember',
> - 'data': { 'name': 'str' } }
> + 'data': { 'name': 'str', '*features': [ 'str' ] } }
>
> ##
> # @SchemaInfoArray:
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index 819ea6ad97..3cb389e875 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -472,7 +472,7 @@ def check_enum(expr: _JSONObject, info:
> QAPISourceInfo) -> None:
> for m in members]
> for member in members:
> source = "'data' member"
> - check_keys(member, info, source, ['name'], ['if'])
> + check_keys(member, info, source, ['name'], ['if', 'features'])
> member_name = member['name']
> check_name_is_str(member_name, info, source)
> source = "%s '%s'" % (source, member_name)
> @@ -483,6 +483,7 @@ def check_enum(expr: _JSONObject, info:
> QAPISourceInfo) -> None:
> permit_upper=permissive,
> permit_underscore=permissive)
> check_if(member, info, source)
> + check_features(member.get('features'), info)
>
>
> def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index 6334546363..67c7d89aae 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -275,12 +275,13 @@ def _gen_tree(self, name: str, mtype: str, obj:
> Dict[str, object],
> obj['features'] = self._gen_features(features)
> self._trees.append(Annotated(obj, ifcond, comment))
>
> - @staticmethod
> - def _gen_enum_member(member: QAPISchemaEnumMember
> + def _gen_enum_member(self, member: QAPISchemaEnumMember
> ) -> Annotated[SchemaInfoEnumMember]:
> obj: SchemaInfoEnumMember = {
> 'name': member.name,
> }
> + if member.features:
> + obj['features'] = self._gen_features(member.features)
> return Annotated(obj, member.ifcond)
>
> def _gen_object_member(self, member: QAPISchemaObjectTypeMember
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index 004d7095ff..6d5f46509a 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
> @@ -708,6 +708,19 @@ def describe(self, info):
> class QAPISchemaEnumMember(QAPISchemaMember):
> role = 'value'
>
> + def __init__(self, name, info, ifcond=None, features=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):
> + super().connect_doc(doc)
> + if doc:
> + for f in self.features:
> + doc.connect_feature(f)
> +
>
> class QAPISchemaFeature(QAPISchemaMember):
> role = 'feature'
> @@ -980,9 +993,14 @@ def _make_features(self, features, info):
> QAPISchemaIfCond(f.get('if')))
> for f in features]
>
> + def _make_enum_member(self, name, ifcond, features, info):
> + return QAPISchemaEnumMember(name, info,
> + QAPISchemaIfCond(ifcond),
> + self._make_features(features, info))
> +
> def _make_enum_members(self, values, info):
> - return [QAPISchemaEnumMember(v['name'], info,
> - QAPISchemaIfCond(v.get('if')))
> + 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):
> diff --git a/tests/qapi-schema/doc-good.json
> b/tests/qapi-schema/doc-good.json
> index 86dc25d2bd..74745fb405 100644
> --- a/tests/qapi-schema/doc-good.json
> +++ b/tests/qapi-schema/doc-good.json
> @@ -58,11 +58,14 @@
> #
> # Features:
> # @enum-feat: Also _one_ {and only}
> +# @enum-member-feat: a member feature
> #
> # @two is undocumented
> ##
> { 'enum': 'Enum',
> - 'data': [ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
> + 'data': [ { 'name': 'one', 'if': 'IFONE',
> + 'features': [ 'enum-member-feat' ] },
> + 'two' ],
> 'features': [ 'enum-feat' ],
> 'if': 'IFCOND' }
>
> diff --git a/tests/qapi-schema/doc-good.out
> b/tests/qapi-schema/doc-good.out
> index 5a324e2627..9dd65b9d92 100644
> --- a/tests/qapi-schema/doc-good.out
> +++ b/tests/qapi-schema/doc-good.out
> @@ -13,6 +13,7 @@ module doc-good.json
> enum Enum
> member one
> if IFONE
> + feature enum-member-feat
> member two
> if IFCOND
> feature enum-feat
> @@ -108,6 +109,8 @@ The _one_ {and only}
>
> feature=enum-feat
> Also _one_ {and only}
> + feature=enum-member-feat
> +a member feature
> section=None
> @two is undocumented
> doc symbol=Base
> diff --git a/tests/qapi-schema/doc-good.txt
> b/tests/qapi-schema/doc-good.txt
> index 701402ee5e..b3b76bd43f 100644
> --- a/tests/qapi-schema/doc-good.txt
> +++ b/tests/qapi-schema/doc-good.txt
> @@ -56,6 +56,9 @@ Features
> "enum-feat"
> Also _one_ {and only}
>
> +"enum-member-feat"
> + a member feature
> +
> "two" is undocumented
>
>
> diff --git a/tests/qapi-schema/enum-dict-member-unknown.err
> b/tests/qapi-schema/enum-dict-member-unknown.err
> index f8617ea179..235cde0c49 100644
> --- a/tests/qapi-schema/enum-dict-member-unknown.err
> +++ b/tests/qapi-schema/enum-dict-member-unknown.err
> @@ -1,3 +1,3 @@
> enum-dict-member-unknown.json: In enum 'MyEnum':
> enum-dict-member-unknown.json:2: 'data' member has unknown key 'bad-key'
> -Valid keys are 'if', 'name'.
> +Valid keys are 'features', 'if', 'name'.
> diff --git a/tests/qapi-schema/qapi-schema-test.json
> b/tests/qapi-schema/qapi-schema-test.json
> index 2ec50109cb..b677ab861d 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -301,7 +301,8 @@
> 'TEST_IF_COND_2'] } } ] }
>
> { 'enum': 'FeatureEnum1',
> - 'data': [ 'eins', 'zwei', 'drei' ],
> + 'data': [ 'eins', 'zwei',
> + { 'name': 'drei', 'features': [ 'deprecated' ] } ],
> 'features': [ 'feature1' ] }
>
> { 'union': 'FeatureUnion1',
> diff --git a/tests/qapi-schema/qapi-schema-test.out
> b/tests/qapi-schema/qapi-schema-test.out
> index 9337adc9ea..16846dbeb8 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -341,6 +341,7 @@ enum FeatureEnum1
> member eins
> member zwei
> member drei
> + feature deprecated
> feature feature1
> object q_obj_FeatureUnion1-base
> member tag: FeatureEnum1 optional=False
> diff --git a/tests/qapi-schema/test-qapi.py
> b/tests/qapi-schema/test-qapi.py
> index c717a7a90b..2160cef082 100755
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -37,6 +37,7 @@ def visit_enum_type(self, name, info, ifcond, features,
> members, prefix):
> for m in members:
> print(' member %s' % m.name)
> self._print_if(m.ifcond, indent=8)
> + self._print_features(m.features, indent=8)
> self._print_if(ifcond)
> self._print_features(features)
>
> --
> 2.31.1
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20211026/b867da27/attachment-0001.htm>
More information about the libvir-list
mailing list