Eric Blake <ebl...@redhat.com> writes: > The whole point of an alternate is to allow some type-safety while > still accepting more than one JSON type. Meanwhile, the 'any' > type exists to bypass type-safety altogether. The two are > incompatible: you can't accept every type, and still tell which > branch of the alternate to use for the parse; fix this to give a > sane error instead of a Python stack trace. > > Signed-off-by: Eric Blake <ebl...@redhat.com> > > --- > v11: new patch > --- > scripts/qapi.py | 5 ++++- > tests/Makefile | 1 + > tests/qapi-schema/alternate-any.err | 1 + > tests/qapi-schema/alternate-any.exit | 1 + > tests/qapi-schema/alternate-any.json | 4 ++++ > tests/qapi-schema/alternate-any.out | 0 > 6 files changed, 11 insertions(+), 1 deletion(-) > create mode 100644 tests/qapi-schema/alternate-any.err > create mode 100644 tests/qapi-schema/alternate-any.exit > create mode 100644 tests/qapi-schema/alternate-any.json > create mode 100644 tests/qapi-schema/alternate-any.out > > diff --git a/scripts/qapi.py b/scripts/qapi.py > index f97236f..17bf633 100644 > --- a/scripts/qapi.py > +++ b/scripts/qapi.py > @@ -629,7 +629,10 @@ def check_alternate(expr, expr_info): > value, > allow_metas=['built-in', 'union', 'struct', 'enum']) > qtype = find_alternate_member_qtype(value) > - assert qtype > + if not qtype: > + raise QAPIExprError(expr_info, > + "Alternate '%s' member '%s' cannot use " > + "type '%s'" % (name, key, value)) > if qtype in types_seen: > raise QAPIExprError(expr_info, > "Alternate '%s' member '%s' can't "
Interestingly, find_alternate_member_qtype(T) can return None in two ways: when builtin_types[T] is None (only for T == 'any'), and when T is neither built-in, struct, enum or union (it must be alternate then). This leads to the question whether this patch catches exactly 'any', as the commit message claims, or alternate as well. > diff --git a/tests/Makefile b/tests/Makefile > index c1c605f..7c66d16 100644 > --- a/tests/Makefile > +++ b/tests/Makefile > @@ -241,6 +241,7 @@ check-qtest-xtensaeb-y = $(check-qtest-xtensa-y) > > check-qtest-generic-y += tests/qom-test$(EXESUF) > > +qapi-schema += alternate-any.json > qapi-schema += alternate-array.json > qapi-schema += alternate-base.json > qapi-schema += alternate-clash.json > diff --git a/tests/qapi-schema/alternate-any.err > b/tests/qapi-schema/alternate-any.err > new file mode 100644 > index 0000000..aaa0154 > --- /dev/null > +++ b/tests/qapi-schema/alternate-any.err > @@ -0,0 +1 @@ > +tests/qapi-schema/alternate-any.json:2: Alternate 'Alt' member 'one' cannot > use type 'any' > diff --git a/tests/qapi-schema/alternate-any.exit > b/tests/qapi-schema/alternate-any.exit > new file mode 100644 > index 0000000..d00491f > --- /dev/null > +++ b/tests/qapi-schema/alternate-any.exit > @@ -0,0 +1 @@ > +1 > diff --git a/tests/qapi-schema/alternate-any.json > b/tests/qapi-schema/alternate-any.json > new file mode 100644 > index 0000000..e47a73a > --- /dev/null > +++ b/tests/qapi-schema/alternate-any.json > @@ -0,0 +1,4 @@ > +# we do not allow the 'any' type as an alternate branch > +{ 'alternate': 'Alt', > + 'data': { 'one': 'any', > + 'two': 'int' } } > diff --git a/tests/qapi-schema/alternate-any.out > b/tests/qapi-schema/alternate-any.out > new file mode 100644 > index 0000000..e69de29 Could use a test for alternate member of alternate type.