qapi: Pseudo-type '**' is now unused, drop it

'gen': false needs to stay for now, because netdev_add is still using
it.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1442401589-24189-25-git-send-email-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2015-09-16 13:06:27 +02:00
parent b8a98326d5
commit 2d21291ae6
11 changed files with 11 additions and 40 deletions

View File

@ -111,10 +111,7 @@ and field names within a type, should be all lower case with words
separated by a hyphen. However, some existing older commands and separated by a hyphen. However, some existing older commands and
complex types use underscore; when extending such expressions, complex types use underscore; when extending such expressions,
consistency is preferred over blindly avoiding underscore. Event consistency is preferred over blindly avoiding underscore. Event
names should be ALL_CAPS with words separated by underscore. The names should be ALL_CAPS with words separated by underscore.
special string '**' appears for some commands that manually perform
their own type checking rather than relying on the type-safe code
produced by the qapi code generators.
Any name (command, event, type, field, or enum value) beginning with Any name (command, event, type, field, or enum value) beginning with
"x-" is marked experimental, and may be withdrawn or changed "x-" is marked experimental, and may be withdrawn or changed
@ -461,14 +458,11 @@ which would validate this Client JSON Protocol transaction:
<= { "return": [ { "value": "one" }, { } ] } <= { "return": [ { "value": "one" }, { } ] }
In rare cases, QAPI cannot express a type-safe representation of a In rare cases, QAPI cannot express a type-safe representation of a
corresponding Client JSON Protocol command. In these cases, if the corresponding Client JSON Protocol command. You then have to suppress
command expression includes the key 'gen' with boolean value false, generation of a marshalling function by including a key 'gen' with
then the 'data' or 'returns' member that intends to bypass generated boolean value false, and instead write your own function. Please try
type-safety and do its own manual validation should use an inline to avoid adding new commands that rely on this, and instead use
dictionary definition, with a value of '**' rather than a valid type type-safe unions. For an example of this usage:
name for the keys that the generated code will not validate. Please
try to avoid adding new commands that rely on this, and instead use
type-safe unions. For an example of bypass usage:
{ 'command': 'netdev_add', { 'command': 'netdev_add',
'data': {'type': 'str', 'id': 'str'}, 'data': {'type': 'str', 'id': 'str'},

View File

@ -428,15 +428,12 @@ def is_enum(name):
def check_type(expr_info, source, value, allow_array = False, def check_type(expr_info, source, value, allow_array = False,
allow_dict = False, allow_optional = False, allow_dict = False, allow_optional = False,
allow_star = False, allow_metas = []): allow_metas = []):
global all_names global all_names
if value is None: if value is None:
return return
if allow_star and value == '**':
return
# Check if array type for value is okay # Check if array type for value is okay
if isinstance(value, list): if isinstance(value, list):
if not allow_array: if not allow_array:
@ -450,10 +447,6 @@ def check_type(expr_info, source, value, allow_array = False,
# Check if type name for value is okay # Check if type name for value is okay
if isinstance(value, str): if isinstance(value, str):
if value == '**':
raise QAPIExprError(expr_info,
"%s uses '**' but did not request 'gen':false"
% source)
if not value in all_names: if not value in all_names:
raise QAPIExprError(expr_info, raise QAPIExprError(expr_info,
"%s uses unknown type '%s'" "%s uses unknown type '%s'"
@ -479,7 +472,7 @@ def check_type(expr_info, source, value, allow_array = False,
# Todo: allow dictionaries to represent default values of # Todo: allow dictionaries to represent default values of
# an optional argument. # an optional argument.
check_type(expr_info, "Member '%s' of %s" % (key, source), arg, check_type(expr_info, "Member '%s' of %s" % (key, source), arg,
allow_array=True, allow_star=allow_star, allow_array=True,
allow_metas=['built-in', 'union', 'alternate', 'struct', allow_metas=['built-in', 'union', 'alternate', 'struct',
'enum']) 'enum'])
@ -499,18 +492,16 @@ def check_member_clash(expr_info, base_name, data, source = ""):
def check_command(expr, expr_info): def check_command(expr, expr_info):
name = expr['command'] name = expr['command']
allow_star = expr.has_key('gen')
check_type(expr_info, "'data' for command '%s'" % name, check_type(expr_info, "'data' for command '%s'" % name,
expr.get('data'), allow_dict=True, allow_optional=True, expr.get('data'), allow_dict=True, allow_optional=True,
allow_metas=['struct'], allow_star=allow_star) allow_metas=['struct'])
returns_meta = ['union', 'struct'] returns_meta = ['union', 'struct']
if name in returns_whitelist: if name in returns_whitelist:
returns_meta += ['built-in', 'alternate', 'enum'] returns_meta += ['built-in', 'alternate', 'enum']
check_type(expr_info, "'returns' for command '%s'" % name, check_type(expr_info, "'returns' for command '%s'" % name,
expr.get('returns'), allow_array=True, expr.get('returns'), allow_array=True,
allow_optional=True, allow_metas=returns_meta, allow_optional=True, allow_metas=returns_meta)
allow_star=allow_star)
def check_event(expr, expr_info): def check_event(expr, expr_info):
global events global events
@ -1122,7 +1113,6 @@ class QAPISchema(object):
('bool', 'boolean', 'bool', 'false'), ('bool', 'boolean', 'bool', 'false'),
('any', 'value', 'QObject' + pointer_suffix, 'NULL')]: ('any', 'value', 'QObject' + pointer_suffix, 'NULL')]:
self._def_builtin_type(*t) self._def_builtin_type(*t)
self._entity_dict['**'] = self.lookup_type('any') # TODO drop this alias
def _make_implicit_enum_type(self, name, values): def _make_implicit_enum_type(self, name, values):
name = name + 'Kind' name = name + 'Kind'
@ -1272,8 +1262,6 @@ class QAPISchema(object):
def visit(self, visitor): def visit(self, visitor):
visitor.visit_begin(self) visitor.visit_begin(self)
for name in sorted(self._entity_dict.keys()): for name in sorted(self._entity_dict.keys()):
if self._entity_dict[name].name != name:
continue # ignore alias TODO drop alias and remove
self._entity_dict[name].visit(visitor) self._entity_dict[name].visit(visitor)
visitor.visit_end() visitor.visit_end()

View File

@ -234,7 +234,7 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
bad-type-dict.json double-data.json unknown-expr-key.json \ bad-type-dict.json double-data.json unknown-expr-key.json \
redefined-type.json redefined-command.json redefined-builtin.json \ redefined-type.json redefined-command.json redefined-builtin.json \
redefined-event.json command-int.json bad-data.json event-max.json \ redefined-event.json command-int.json bad-data.json event-max.json \
type-bypass.json type-bypass-no-gen.json type-bypass-bad-gen.json \ type-bypass-bad-gen.json \
args-invalid.json \ args-invalid.json \
args-array-empty.json args-array-unknown.json args-int.json \ args-array-empty.json args-array-unknown.json args-int.json \
args-unknown.json args-member-unknown.json args-member-array.json \ args-unknown.json args-member-unknown.json args-member-array.json \

View File

@ -1 +0,0 @@
tests/qapi-schema/type-bypass-no-gen.json:2: Member 'arg' of 'data' for command 'unsafe' uses '**' but did not request 'gen':false

View File

@ -1 +0,0 @@
1

View File

@ -1,2 +0,0 @@
# type bypass only works with 'gen':false
{ 'command': 'unsafe', 'data': { 'arg': '**' }, 'returns': '**' }

View File

@ -1 +0,0 @@
0

View File

@ -1,2 +0,0 @@
# Use of 'gen':false allows bypassing type system
{ 'command': 'unsafe', 'data': { 'arg': '**' }, 'returns': '**', 'gen': false }

View File

@ -1,4 +0,0 @@
object :obj-unsafe-arg
member arg: any optional=False
command unsafe :obj-unsafe-arg -> any
gen=False success_response=True