[PATCH v3 25/34] qapi: New special feature flag "deprecated"

Markus Armbruster posted 34 patches 5 years, 11 months ago
Maintainers: Eric Blake <eblake@redhat.com>, Michael Roth <mdroth@linux.vnet.ibm.com>, Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Markus Armbruster <armbru@redhat.com>, Eduardo Habkost <ehabkost@redhat.com>, "Dr. David Alan Gilbert" <dgilbert@redhat.com>, Juan Quintela <quintela@redhat.com>
There is a newer version of this series
[PATCH v3 25/34] qapi: New special feature flag "deprecated"
Posted by Markus Armbruster 5 years, 11 months ago
Unlike regular feature flags, the new special feature flag
"deprecated" is recognized by the QAPI generator.  For now, it's only
permitted with commands, events, and struct members.  It will be put
to use shortly.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 docs/devel/qapi-code-gen.txt                    | 6 ++++++
 scripts/qapi/schema.py                          | 6 ++++++
 tests/Makefile.include                          | 1 +
 tests/qapi-schema/features-deprecated-type.err  | 2 ++
 tests/qapi-schema/features-deprecated-type.json | 3 +++
 tests/qapi-schema/features-deprecated-type.out  | 0
 tests/qapi-schema/qapi-schema-test.json         | 6 +++---
 tests/qapi-schema/qapi-schema-test.out          | 6 +++---
 8 files changed, 24 insertions(+), 6 deletions(-)
 create mode 100644 tests/qapi-schema/features-deprecated-type.err
 create mode 100644 tests/qapi-schema/features-deprecated-type.json
 create mode 100644 tests/qapi-schema/features-deprecated-type.out

diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index a1ef1cfd61..823adbabda 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -683,6 +683,12 @@ Intended use is to have each feature string signal that this build of
 QEMU shows a certain behaviour.
 
 
+==== Special features ====
+
+Feature "deprecated" makes a command, event, or struct member as
+deprecated.  It is not supported elsewhere so far.
+
+
 === Naming rules and reserved names ===
 
 All names must begin with a letter, and contain only ASCII letters,
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 6ee3677215..78309a00f0 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -193,6 +193,12 @@ class QAPISchemaType(QAPISchemaEntity):
             return None
         return self.name
 
+    def check(self, schema):
+        QAPISchemaEntity.check(self, schema)
+        if 'deprecated' in [f.name for f in self.features]:
+            raise QAPISemError(
+                self.info, "feature 'deprecated' is not supported for types")
+
     def describe(self):
         assert self.meta
         return "%s type '%s'" % (self.meta, self.name)
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 67e8fcddda..d1340301b2 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -242,6 +242,7 @@ qapi-schema += event-case.json
 qapi-schema += event-member-invalid-dict.json
 qapi-schema += event-nest-struct.json
 qapi-schema += features-bad-type.json
+qapi-schema += features-deprecated-type.json
 qapi-schema += features-duplicate-name.json
 qapi-schema += features-if-invalid.json
 qapi-schema += features-missing-name.json
diff --git a/tests/qapi-schema/features-deprecated-type.err b/tests/qapi-schema/features-deprecated-type.err
new file mode 100644
index 0000000000..af4ffe20aa
--- /dev/null
+++ b/tests/qapi-schema/features-deprecated-type.err
@@ -0,0 +1,2 @@
+features-deprecated-type.json: In struct 'S':
+features-deprecated-type.json:2: feature 'deprecated' is not supported for types
diff --git a/tests/qapi-schema/features-deprecated-type.json b/tests/qapi-schema/features-deprecated-type.json
new file mode 100644
index 0000000000..4b5bf5b86e
--- /dev/null
+++ b/tests/qapi-schema/features-deprecated-type.json
@@ -0,0 +1,3 @@
+# Feature 'deprecated' is not supported for types
+{ 'struct': 'S', 'data': {},
+  'features': [ 'deprecated' ] }
diff --git a/tests/qapi-schema/features-deprecated-type.out b/tests/qapi-schema/features-deprecated-type.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index f576c337af..6b1f05afa7 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -258,7 +258,7 @@
   'data': { 'foo': 'int' },
   'features': [] }
 { 'struct': 'FeatureStruct1',
-  'data': { 'foo': { 'type': 'int', 'features': [ 'member-feature1' ] } },
+  'data': { 'foo': { 'type': 'int', 'features': [ 'deprecated' ] } },
   'features': [ 'feature1' ] }
 { 'struct': 'FeatureStruct2',
   'data': { 'foo': 'int' },
@@ -308,7 +308,7 @@
   'features': [] }
 
 { 'command': 'test-command-features1',
-  'features': [ 'feature1' ] }
+  'features': [ 'deprecated' ] }
 { 'command': 'test-command-features3',
   'features': [ 'feature1', 'feature2' ] }
 
@@ -322,4 +322,4 @@
                                               'defined(TEST_IF_COND_2)'] } ] }
 
 { 'event': 'TEST-EVENT-FEATURES1',
-  'features': [ 'feature1' ] }
+  'features': [ 'deprecated' ] }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index cd863ae966..891b4101e0 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -359,7 +359,7 @@ object FeatureStruct0
     member foo: int optional=False
 object FeatureStruct1
     member foo: int optional=False
-        feature member-feature1
+        feature deprecated
     feature feature1
 object FeatureStruct2
     member foo: int optional=False
@@ -419,7 +419,7 @@ command test-features0 q_obj_test-features0-arg -> None
     gen=True success_response=True boxed=False oob=False preconfig=False
 command test-command-features1 None -> None
     gen=True success_response=True boxed=False oob=False preconfig=False
-    feature feature1
+    feature deprecated
 command test-command-features3 None -> None
     gen=True success_response=True boxed=False oob=False preconfig=False
     feature feature1
@@ -440,7 +440,7 @@ command test-command-cond-features3 None -> None
         if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)']
 event TEST-EVENT-FEATURES1 None
     boxed=False
-    feature feature1
+    feature deprecated
 module include/sub-module.json
 include sub-sub-module.json
 object SecondArrayRef
-- 
2.21.1


Re: [PATCH v3 25/34] qapi: New special feature flag "deprecated"
Posted by Philippe Mathieu-Daudé 5 years, 11 months ago
On 3/15/20 3:46 PM, Markus Armbruster wrote:
> Unlike regular feature flags, the new special feature flag
> "deprecated" is recognized by the QAPI generator.  For now, it's only
> permitted with commands, events, and struct members.  It will be put
> to use shortly.

What about using a '@DeprecatedSince' tag?
Ah, that would apply to the whole structure and not a particular member...

I am wondering because sometimes we deprecate something for 2 releases 
but then once the deadline passed we forgot to remove it. Having the 
release version deadline along with deprecation would help automating 
removal checks.
Maybe we can use a tag with release version, such 'deprecated_since:5.0'?

> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>   docs/devel/qapi-code-gen.txt                    | 6 ++++++
>   scripts/qapi/schema.py                          | 6 ++++++
>   tests/Makefile.include                          | 1 +
>   tests/qapi-schema/features-deprecated-type.err  | 2 ++
>   tests/qapi-schema/features-deprecated-type.json | 3 +++
>   tests/qapi-schema/features-deprecated-type.out  | 0
>   tests/qapi-schema/qapi-schema-test.json         | 6 +++---
>   tests/qapi-schema/qapi-schema-test.out          | 6 +++---
>   8 files changed, 24 insertions(+), 6 deletions(-)
>   create mode 100644 tests/qapi-schema/features-deprecated-type.err
>   create mode 100644 tests/qapi-schema/features-deprecated-type.json
>   create mode 100644 tests/qapi-schema/features-deprecated-type.out
> 
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index a1ef1cfd61..823adbabda 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -683,6 +683,12 @@ Intended use is to have each feature string signal that this build of
>   QEMU shows a certain behaviour.
>   
>   
> +==== Special features ====
> +
> +Feature "deprecated" makes a command, event, or struct member as
> +deprecated.  It is not supported elsewhere so far.
> +
> +
>   === Naming rules and reserved names ===
>   
>   All names must begin with a letter, and contain only ASCII letters,
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index 6ee3677215..78309a00f0 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
> @@ -193,6 +193,12 @@ class QAPISchemaType(QAPISchemaEntity):
>               return None
>           return self.name
>   
> +    def check(self, schema):
> +        QAPISchemaEntity.check(self, schema)
> +        if 'deprecated' in [f.name for f in self.features]:
> +            raise QAPISemError(
> +                self.info, "feature 'deprecated' is not supported for types")
> +
>       def describe(self):
>           assert self.meta
>           return "%s type '%s'" % (self.meta, self.name)
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 67e8fcddda..d1340301b2 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -242,6 +242,7 @@ qapi-schema += event-case.json
>   qapi-schema += event-member-invalid-dict.json
>   qapi-schema += event-nest-struct.json
>   qapi-schema += features-bad-type.json
> +qapi-schema += features-deprecated-type.json
>   qapi-schema += features-duplicate-name.json
>   qapi-schema += features-if-invalid.json
>   qapi-schema += features-missing-name.json
> diff --git a/tests/qapi-schema/features-deprecated-type.err b/tests/qapi-schema/features-deprecated-type.err
> new file mode 100644
> index 0000000000..af4ffe20aa
> --- /dev/null
> +++ b/tests/qapi-schema/features-deprecated-type.err
> @@ -0,0 +1,2 @@
> +features-deprecated-type.json: In struct 'S':
> +features-deprecated-type.json:2: feature 'deprecated' is not supported for types
> diff --git a/tests/qapi-schema/features-deprecated-type.json b/tests/qapi-schema/features-deprecated-type.json
> new file mode 100644
> index 0000000000..4b5bf5b86e
> --- /dev/null
> +++ b/tests/qapi-schema/features-deprecated-type.json
> @@ -0,0 +1,3 @@
> +# Feature 'deprecated' is not supported for types
> +{ 'struct': 'S', 'data': {},
> +  'features': [ 'deprecated' ] }
> diff --git a/tests/qapi-schema/features-deprecated-type.out b/tests/qapi-schema/features-deprecated-type.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
> index f576c337af..6b1f05afa7 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -258,7 +258,7 @@
>     'data': { 'foo': 'int' },
>     'features': [] }
>   { 'struct': 'FeatureStruct1',
> -  'data': { 'foo': { 'type': 'int', 'features': [ 'member-feature1' ] } },
> +  'data': { 'foo': { 'type': 'int', 'features': [ 'deprecated' ] } },
>     'features': [ 'feature1' ] }
>   { 'struct': 'FeatureStruct2',
>     'data': { 'foo': 'int' },
> @@ -308,7 +308,7 @@
>     'features': [] }
>   
>   { 'command': 'test-command-features1',
> -  'features': [ 'feature1' ] }
> +  'features': [ 'deprecated' ] }
>   { 'command': 'test-command-features3',
>     'features': [ 'feature1', 'feature2' ] }
>   
> @@ -322,4 +322,4 @@
>                                                 'defined(TEST_IF_COND_2)'] } ] }
>   
>   { 'event': 'TEST-EVENT-FEATURES1',
> -  'features': [ 'feature1' ] }
> +  'features': [ 'deprecated' ] }
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index cd863ae966..891b4101e0 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -359,7 +359,7 @@ object FeatureStruct0
>       member foo: int optional=False
>   object FeatureStruct1
>       member foo: int optional=False
> -        feature member-feature1
> +        feature deprecated
>       feature feature1
>   object FeatureStruct2
>       member foo: int optional=False
> @@ -419,7 +419,7 @@ command test-features0 q_obj_test-features0-arg -> None
>       gen=True success_response=True boxed=False oob=False preconfig=False
>   command test-command-features1 None -> None
>       gen=True success_response=True boxed=False oob=False preconfig=False
> -    feature feature1
> +    feature deprecated
>   command test-command-features3 None -> None
>       gen=True success_response=True boxed=False oob=False preconfig=False
>       feature feature1
> @@ -440,7 +440,7 @@ command test-command-cond-features3 None -> None
>           if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)']
>   event TEST-EVENT-FEATURES1 None
>       boxed=False
> -    feature feature1
> +    feature deprecated
>   module include/sub-module.json
>   include sub-sub-module.json
>   object SecondArrayRef
> 


Re: [PATCH v3 25/34] qapi: New special feature flag "deprecated"
Posted by Markus Armbruster 5 years, 11 months ago
Philippe Mathieu-Daudé <philmd@redhat.com> writes:

> On 3/15/20 3:46 PM, Markus Armbruster wrote:
>> Unlike regular feature flags, the new special feature flag
>> "deprecated" is recognized by the QAPI generator.  For now, it's only
>> permitted with commands, events, and struct members.  It will be put
>> to use shortly.
>
> What about using a '@DeprecatedSince' tag?
> Ah, that would apply to the whole structure and not a particular member...
>
> I am wondering because sometimes we deprecate something for 2 releases
> but then once the deadline passed we forgot to remove it. Having the
> release version deadline along with deprecation would help automating
> removal checks.
> Maybe we can use a tag with release version, such 'deprecated_since:5.0'?

Intended consumer for "since <version>" information?

So far, it's been just developers.  Searching the QAPI schema for
deprecated stuff past its grace period hasn't been the problem;
remembering to search for it has been.