summaryrefslogtreecommitdiffstats
path: root/scripts/qapi/schema.py
Commit message (Collapse)AuthorAgeFilesLines
* qapi/introspect.py: add type hint annotationsJohn Snow2021-02-181-1/+1
| | | | | | | | | | | | | | | | | | | NB: The type aliases (SchemaInfo et al) declare intent for some of the "dictly-typed" objects we pass around in introspect.py. They do not enforce the shape of those objects, and cannot, until Python 3.7 or later. (And even then, it may not be "worth it".) Annotations are also added to the QAPISchemaEntity __init__ method in schema.py to allow mypy to statically prove the type of typ.name, needed to prove the return type of QAPISchemaGenIntrospectVisitor._use_type(). Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-15-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Note on QAPISchemaEntity.__init__() squashed into commit message, Comment wrapped to conform to PEP 8] Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: centralize the built-in module name definitionJohn Snow2021-02-081-5/+8
| | | | | | | | | Use a constant to make it obvious we're referring to a very specific thing. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210201193747.2169670-11-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: use './builtin' as the built-in module nameJohn Snow2021-02-081-10/+10
| | | | | | | | | | Use './builtin' as the built-in module name instead of None. Clarify the typing that this is now always a string. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210201193747.2169670-9-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: centralize is_[user|system|builtin]_module methodsJohn Snow2021-02-081-2/+29
| | | | | | | | | | Define what a module is and define what kind of a module it is once and for all, in one place. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210201193747.2169670-6-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: establish mypy type-checking baselineJohn Snow2020-10-101-1/+2
| | | | | | | | | | | | | | | | | | | Fix a minor typing issue, and then establish a mypy type-checking baseline. Like pylint, this should be run from the folder above: > mypy --config-file=qapi/mypy.ini qapi/ This is designed and tested for mypy 0.770 or greater. Signed-off-by: John Snow <jsnow@redhat.com> Tested-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Tested-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20201009161558.107041-19-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/common.py: delint with pylintJohn Snow2020-10-101-7/+7
| | | | | | | | | | | | | | | | At this point, that just means using a consistent strategy for constant names. constants get UPPER_CASE and names not used externally get a leading underscore. As a preference, while renaming constants to be UPPERCASE, move them to the head of the file. Generally, it's nice to be able to audit the code that runs on import in one central place. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20201009161558.107041-13-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: delint using flake8John Snow2020-10-101-3/+5
| | | | | | | | | | | | | | | | | Petty style guide fixes and line length enforcement. Not a big win, not a big loss, but flake8 passes 100% on the qapi module, which gives us an easy baseline to enforce hereafter. A note on the flake8 exception: flake8 will warn on *any* bare except, but pylint's is context-aware and will suppress the warning if you re-raise the exception. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20201009161558.107041-9-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: enforce import order/styling with isortJohn Snow2020-10-101-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While we're mucking around with imports, we might as well formalize the style we use. Let's use isort to do it for us. lines_after_imports=2: Use two lines after imports, to match PEP8's desire to have "two lines before and after" class definitions, which are likely to start immediately after imports. force_sort_within_sections: Intermingles "from x" and "import x" style statements, such that sorting is always performed strictly on the module name itself. force_grid_wrap=4: Four or more imports from a single module will force the one-per-line style that's more git-friendly. This will generally happen for 'typing' imports. multi_line_output=3: Uses the one-per-line indented style for long imports. include_trailing_comma: Adds a comma to the last import in a group, which makes git conflicts nicer to deal with, generally. line_length: 72 is chosen to match PEP8's "docstrings and comments" line length limit. If you have a single line import that exceeds 72 characters, your names are too long! Suggested-by: Cleber Rosa <crosa@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Tested-by: Cleber Rosa <crosa@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20201009161558.107041-8-jsnow@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: Prefer explicit relative importsJohn Snow2020-10-101-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | All of the QAPI include statements are changed to be package-aware, as explicit relative imports. A quirk of Python packages is that the name of the package exists only *outside* of the package. This means that to a module inside of the qapi folder, there is inherently no such thing as the "qapi" package. The reason these imports work is because the "qapi" package exists in the context of the caller -- the execution shim, where sys.path includes a directory that has a 'qapi' folder in it. When we write "from qapi import sibling", we are NOT referencing the folder 'qapi', but rather "any package named qapi in sys.path". If you should so happen to have a 'qapi' package in your path, it will use *that* package. When we write "from .sibling import foo", we always reference explicitly our sibling module; guaranteeing consistency in *where* we are importing these modules from. This can be useful when working with virtual environments and packages in development mode. In development mode, a package is installed as a series of symlinks that forwards to your same source files. The problem arises because code quality checkers will follow "import qapi.x" to the "installed" version instead of the sibling file and -- even though they are the same file -- they have different module paths, and this causes cyclic import problems, false positive type mismatch errors, and more. It can also be useful when dealing with hierarchical packages, e.g. if we allow qemu.core.qmp, qemu.qapi.parser, etc. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-Id: <20201009161558.107041-6-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: Add a 'coroutine' flag for commandsKevin Wolf2020-10-091-4/+9
| | | | | | | | | | | | | | | | This patch adds a new 'coroutine' flag to QMP command definitions that tells the QMP dispatcher that the command handler is safe to be run in a coroutine. The documentation of the new flag pretends that this flag is already used as intended, which it isn't yet after this patch. We'll implement this in another patch in this series. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20201005155855.256490-9-kwolf@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: New special feature flag "deprecated"Markus Armbruster2020-03-171-0/+6
| | | | | | | | | | | | 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> Message-Id: <20200317115459.31821-26-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Doc typo fixed]
* qapi: Add feature flags to struct membersMarkus Armbruster2020-03-171-5/+20
| | | | | | Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20200317115459.31821-21-armbru@redhat.com>
* qapi/schema: Call QAPIDoc.connect_member() in just one placeMarkus Armbruster2020-03-171-11/+12
| | | | | | | | | | | The .connect_doc() of classes that have QAPISchemaMember connect them to their documentation. Change them to delegate the actual work to new QAPISchemaMember.connect_doc(). Matches the .connect_doc() that already exist. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20200317115459.31821-20-armbru@redhat.com>
* qapi/schema: Rename QAPISchemaObjectType{Variant,Variants}Markus Armbruster2020-03-171-11/+11
| | | | | | | | | | | QAPISchemaObjectTypeVariants represents both object type and alternate type variants. Rename to QAPISchemaVariants. Rename QAPISchemaObjectTypeVariant the same way. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20200317115459.31821-19-armbru@redhat.com>
* qapi/schema: Reorder classes so related ones are togetherMarkus Armbruster2020-03-171-134/+134
| | | | | | | | | | Move QAPISchemaAlternateType up some, so that all QAPISchemaFOOType are together. Move QAPISchemaObjectTypeVariants right behind its users. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20200317115459.31821-18-armbru@redhat.com>
* qapi/schema: Change _make_features() to a take feature listMarkus Armbruster2020-03-171-8/+9
| | | | | | | | | | | QAPISchema._make_features() takes a definition expression, and extracts its 'features' member. The other ._make_FOO() leave destructuring expressions to their callers. Change ._make_features() to match them. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20200317115459.31821-17-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Consistently put @features parameter right after @ifcondMarkus Armbruster2020-03-171-19/+17Star
| | | | | | | Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20200317115459.31821-14-armbru@redhat.com>
* qapi: Add feature flags to remaining definitionsMarkus Armbruster2020-03-171-43/+53
| | | | | | | | | | | | | | | | | In v4.1.0, we added feature flags just to struct types (commit 6a8c0b5102^..f3ed93d545), to satisfy an immediate need (commit c9d4070991 "file-posix: Add dynamic-auto-read-only QAPI feature"). In v4.2.0, we added them to commands (commit 23394b4c39 "qapi: Add feature flags to commands") to satisfy another immediate need (commit d76744e65e "qapi: Allow introspecting fix for savevm's cooperation with blockdev"). Add them to the remaining definitions: enumeration types, union types, alternate types, and events. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20200317115459.31821-13-armbru@redhat.com>
* qapi/schema: Clean up around QAPISchemaEntity.connect_doc()Markus Armbruster2020-03-171-4/+9
| | | | | | | | | | | | QAPISchemaEntity calls doc.connect_feature() in .check(). Improper since commit ee1e6a1f6c8 split .connect_doc() off .check(). Move the call. Requires making the children call super().connect_doc() as they should. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20200317115459.31821-12-armbru@redhat.com>
* qapi: Brush off some (py)lintMarkus Armbruster2020-03-051-6/+5Star
| | | | | | Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20200304155932.20452-5-armbru@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com>
* qapi: Use super() now we have Python 3Markus Armbruster2020-03-051-26/+25Star
| | | | | | Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20200304155932.20452-4-armbru@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com>
* qapi: Inheriting from object is pointless with Python 3, dropMarkus Armbruster2020-03-051-6/+6
| | | | | | | Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-Id: <20200304155932.20452-2-armbru@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com>
* qapi: Fix code generation with Python 3.5Markus Armbruster2020-01-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Recent commit 3e7fb5811b "qapi: Fix code generation for empty modules" modules" switched QAPISchema.visit() from for entity in self._entity_list: effectively to for mod in self._module_dict.values(): for entity in mod._entity_list: Visits in the same order as long as .values() is in insertion order. That's the case only for Python 3.6 and later. Before, it's in some arbitrary order, which results in broken generated code. Fix by making self._module_dict an OrderedDict rather than a dict. Fixes: 3e7fb5811baab213dcc7149c3aa69442d683c26c Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Tested-by: Thomas Huth <thuth@redhat.com> Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com> Tested-by: BALATON Zoltan <balaton@eik.bme.hu> Tested-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20200116202558.31473-1-armbru@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
* qapi: Fix code generation for empty modulesMarkus Armbruster2020-01-141-11/+13
| | | | | | | | | | | | | | | | | | | When a sub-module doesn't contain any definitions, we don't generate code for it, but we do generate the #include. We generate code only for modules that get visited. QAPISchema.visit() visits only modules that have definitions. It can visit modules multiple times. Clean this up as follows. Collect entities in their QAPISchemaModule. Have QAPISchema.visit() call QAPISchemaModule.visit() for each module. Have QAPISchemaModule.visit() call .visit_module() for itself, and QAPISchemaEntity.visit() for each of its entities. This way, we visit each module exactly once. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191120182551.23795-6-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Proper intermediate representation for modulesMarkus Armbruster2020-01-141-20/+43
| | | | | | | | | | | | | | | | Modules are represented only by their names so far. Introduce class QAPISchemaModule. So far, it merely wraps the name. The next patch will put it to more interesting use. Once again, arrays spice up the patch a bit. For any other type, @info points to the definition, which lets us map from @info to module. For arrays, there is no definition, and @info points to the first use instead. We have to use the element type's module instead, which is only available after .check(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191120182551.23795-5-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Tweak "command returns a nice type" check for clarityMarkus Armbruster2020-01-141-4/+5
| | | | | | Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191120182551.23795-2-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Check feature documentation against the schemaMarkus Armbruster2019-10-291-0/+2
| | | | | | | | | Commit f3ed93d545 "qapi: Allow documentation for features" neglected to check documentation against the schema. Fix that: check them the same way we check arguments. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-20-armbru@redhat.com>
* qapi: Lift features into QAPISchemaEntityMarkus Armbruster2019-10-291-21/+11Star
| | | | | | | | | | | | | | Commit 6a8c0b5102 "qapi: Add feature flags to struct types" added features to QAPISchemaObjectType. Commit a95daa5093 "qapi: Add feature flags to commands in qapi" added them to QAPISchemaCommand, duplicating the code. Tolerable, but the duplication will only get worse as we add features to more definitions. To de-duplicate, lift features from QAPISchemaObjectType and QAPISchemaCommand into QAPISchemaEntity. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-18-armbru@redhat.com>
* qapi: Eliminate .check_doc() overridesMarkus Armbruster2019-10-291-21/+2Star
| | | | | | | | | | | | All sub-classes of QAPISchemaEntity now override .check_doc() the same way, except for QAPISchemaType and and QAPISchemaArrayType. Put the overrides' code in QAPISchemaEntity.check_doc(), and drop the overrides. QAPISchemaType doesn't care because it's abstract. QAPISchemaArrayType doesn't care because its .doc is always None. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-14-armbru@redhat.com>
* qapi: Simplify ._make_implicit_object_type()Markus Armbruster2019-10-291-7/+6Star
| | | | | | | All callers now pass doc=None. Drop the argument. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-13-armbru@redhat.com>
* qapi: Fix doc comment checking for commands and eventsMarkus Armbruster2019-10-291-2/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a command's 'data' is an object, its doc comment describes the arguments defined there. When 'data' names a type, the doc comment does not describe arguments. Instead, the doc generator inserts a pointer to the named type. An event's doc comment works the same. We don't actually check doc comments for commands and events. Instead, QAPISchema._def_command() forwards the doc comment to the implicit argument type, where it gets checked. Works because the check only cares for the implicit argument type's members. Not only is this needlessly hard to understand, it actually falls apart in two cases: * When 'data' is empty, there is nothing to forward to, and the doc comment remains unchecked. Demonstrated by test doc-bad-event-arg. * When 'data' names a type, we can't forward, as the type has its own doc comment. The command or event's doc comment remains unchecked. Demonstrated by test doc-bad-boxed-command-arg. The forwarding goes back to commit 069fb5b250 "qapi: Prepare for requiring more complete documentation", put to use in commit 816a57cd6e "qapi: Fix detection of bogus member documentation". That fix was incomplete. To fix this, make QAPISchemaCommand and QAPISchemaEvent check doc comments, and drop the forwarding of doc comments to implicit argument types. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-12-armbru@redhat.com>
* qapi: Clean up doc comment checking for implicit union baseMarkus Armbruster2019-10-291-11/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An object type's doc comment describes the type's members, less the ones defined in a named base type. Cases: * Struct: the members are defined in 'data' and inherited from 'base'. Since the base type cannot be implicit, the doc comment describes just 'data'. * Simple union: the only member is the implicit tag member @type, and the doc comment describes it. * Flat union with implicit base type: the members are defined in 'base', and the doc comment describes it. * Flat union with named base type: the members are inherited from 'base'. The doc comment describes no members. Before we can check a doc comment with .check_doc(), we need .connect_doc() connect each of its "argument sections" to the member it documents. For structs and simple unions, this is straightforward: the members in question are in .local_members, and .connect_doc() connects them. For flat unions with a named base type, it's trivial: .local_members is empty, and .connect_doc() does nothing. For flat unions with an implicit base type, it's tricky. We have QAPISchema._make_implicit_object_type() forward the union's doc comment to the implicit base type, so that the base type's .connect_doc() connects the members. The union's .connect_doc() does nothing, as .local_members is empty. Dirt effect: we check the doc comment twice, once for the union type, and once for the implicit base type. This is needlessly brittle and hard to understand. Clean up as follows. Make the union's .connect_doc() connect an implicit base's members itself. Do not forward the union's doc comment to its implicit base type. Requires extending .connect_doc() so it can work with a doc comment other than self.doc. Add an optional argument for that. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-11-armbru@redhat.com>
* qapi: Fix enum doc comment checkingMarkus Armbruster2019-10-291-0/+4
| | | | | | | | | | | Enumeration type documentation comments are not checked, as demonstrated by test doc-bad-enum-member. This is because we neglect to call self.doc.check() for enumeration types. Messed up in 816a57cd6e "qapi: Fix detection of bogus member documentation". Fix it. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-10-armbru@redhat.com>
* qapi: Split .connect_doc(), .check_doc() off .check()Markus Armbruster2019-10-291-7/+27
| | | | | | | | | Splitting documentation checking off the .check() methods makes them a bit more focused, which is welcome, as some of them are pretty big. It also prepares the ground for the following commits. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191024110237.30963-9-armbru@redhat.com>
* qapi: Add feature flags to commandsPeter Krempa2019-10-221-4/+18
| | | | | | | | | | | | | | Similarly to features for struct types introduce the feature flags also for commands. This will allow notifying management layers of fixes and compatible changes in the behaviour of a command which may not be detectable any other way. The changes were heavily inspired by commit 6a8c0b51025. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20191018081454.21369-3-armbru@redhat.com>
* qapi: Split up scripts/qapi/common.pyMarkus Armbruster2019-10-221-0/+1043
The QAPI code generator clocks in at some 3100 SLOC in 8 source files. Almost 60% of the code is in qapi/common.py. Split it into more focused modules: * Move QAPISchemaPragma and QAPISourceInfo to qapi/source.py. * Move QAPIError and its sub-classes to qapi/error.py. * Move QAPISchemaParser and QAPIDoc to parser.py. Use the opportunity to put QAPISchemaParser first. * Move check_expr() & friends to qapi/expr.py. Use the opportunity to put the code into a more sensible order. * Move QAPISchema & friends to qapi/schema.py * Move QAPIGen and its sub-classes, ifcontext, QAPISchemaModularCVisitor, and QAPISchemaModularCVisitor to qapi/gen.py * Delete camel_case(), it's unused since commit e98859a9b9 "qapi: Clean up after recent conversions to QAPISchemaVisitor" A number of helper functions remain in qapi/common.py. I considered moving the code generator helpers to qapi/gen.py, but decided not to. Perhaps we should rewrite them as methods of QAPIGen some day. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20191018074345.24034-7-armbru@redhat.com> [Add "# -*- coding: utf-8 -*-" lines]