summaryrefslogtreecommitdiffstats
path: root/scripts/qapi
Commit message (Collapse)AuthorAgeFilesLines
...
* qapi/expr.py: Remove single-letter variableJohn Snow2021-04-301-7/+7
| | | | | | | Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-13-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: Consolidate check_if_str calls in check_ifJohn Snow2021-04-301-17/+16Star
| | | | | | | | | | | | | | | | | | | | | | This is a small rewrite to address some minor style nits. Don't compare against the empty list to check for the empty condition, and move the normalization forward to unify the check on the now-normalized structure. With the check unified, the local nested function isn't needed anymore and can be brought down into the normal flow of the function. With the nesting level changed, shuffle the error strings around a bit to get them to fit in 79 columns. Note: although ifcond is typed as Sequence[str] elsewhere, we *know* that the parser will produce real, bona-fide lists. It's okay to check isinstance(ifcond, list) here. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-12-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: add type hint annotationsJohn Snow2021-04-302-30/+43
| | | | | | | | | | Annotations do not change runtime behavior. This commit *only* adds annotations. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-11-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: Modify check_keys to accept any CollectionJohn Snow2021-04-301-1/+1
| | | | | | | | | | | | | | | | This is a minor adjustment that lets parameters @required and @optional take tuple arguments, in particular (). Later patches will make use of that. (Iterable would also have worked, but Iterable also includes things like generator expressions which are consumed upon iteration, which would require a rewrite to make sure that each input was only traversed once. Collection implies the "can re-iterate" property.) Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-10-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: Add casts in a few select casesJohn Snow2021-04-301-5/+5
| | | | | | | | | | | | | | | | | | Casts are instructions to the type checker only, they aren't "safe" and should probably be avoided in general. In this case, when we perform type checking on a nested structure, the type of each field does not "stick". (See PEP 647 for an example of "type narrowing" that does "stick". It is available in Python 3.10, so we can't use it yet.) We don't need to assert that something is a str if we've already checked or asserted that it is -- use a cast instead for these cases. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-9-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: Check type of union and alternate 'data' memberJohn Snow2021-04-301-0/+7
| | | | | | | | | | | | | | | Prior to this commit, specifying a non-object value here causes the QAPI parser to crash in expr.py with a stack trace with (likely) an AttributeError when we attempt to call that value's items() method. This member needs to be an object (Dict), and not anything else. Add a check for this with a nicer error message, and formalize that check with new test cases that exercise that error. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-8-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: move string check upwards in check_typeJohn Snow2021-04-301-4/+4
| | | | | | | | | | | | | For readability purposes only, shimmy the early return upwards to the top of the function, so cases proceed in order from least to most complex. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-7-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: Add assertion for union type 'check_dict'John Snow2021-04-301-1/+3
| | | | | | | | | | | | | mypy isn't fond of allowing you to check for bool membership in a collection of str elements. Guard this lookup for precisely when we were given a name. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-6-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: constrain incoming expression typesJohn Snow2021-04-301-3/+25
| | | | | | | | | | mypy does not know the types of values stored in Dicts that masquerade as objects. Help the type checker out by constraining the type. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-5-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: Check for dict instead of OrderedDictJohn Snow2021-04-301-3/+2Star
| | | | | | | | | | | | | OrderedDict is a subtype of dict, so we can check for a more general form. These functions do not themselves depend on it being any particular type. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-4-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr.py: Remove 'info' argument from nested check_if_strJohn Snow2021-04-301-3/+3
| | | | | | | | | | | | | The function can just use the argument from the scope above. Otherwise, we get shadowed argument errors because the parameter name clashes with the name of a variable already in-scope. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-3-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/expr: Comment cleanupJohn Snow2021-04-301-1/+1
| | | | | | | | | | | | | | | The linter yaps after 0825f62c842. Fix this trivial issue to restore the linter baseline. (Yes, ideally -- and soon -- the linter will be part of CI so we don't clutter up the log with fixups. For now, though, the baseline is useful for testing intermediate commits as types are added to the QAPI library.) Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-2-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi: Enforce union and alternate branch naming rulesMarkus Armbruster2021-03-231-2/+2
| | | | | | | | | | Union branch names should use '-', not '_'. Enforce this. The only offenders are in tests/. Fix them. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-29-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Commit message typo fixed]
* qapi: Enforce enum member naming rulesMarkus Armbruster2021-03-231-2/+3
| | | | | | | | | | Enum members should use '-', not '_'. Enforce this. Fix the fixable offenders (all in tests/), and add the remainder to pragma member-name-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-28-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Enforce struct member naming rulesMarkus Armbruster2021-03-231-2/+3
| | | | | | | | | | | Struct members, including command arguments, event data, and union inline base members, should use '-', not '_'. Enforce this. Fix the fixable offenders (all in tests/), and add the remainder to pragma member-name-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-27-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Enforce command naming rulesMarkus Armbruster2021-03-233-2/+8
| | | | | | | | | | Command names should be lower-case. Enforce this. Fix the fixable offenders (all in tests/), and add the remainder to pragma command-name-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-25-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Enforce feature naming rulesMarkus Armbruster2021-03-231-1/+1
| | | | | | | | Feature names should use '-', not '_'. Enforce this. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-24-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Prepare for rejecting underscore in command and member namesMarkus Armbruster2021-03-231-10/+14
| | | | | | | | | | | | | Command names and member names within a type should be all lower case with words separated by a hyphen. We also accept underscore. Rework check_name_lower() to optionally reject underscores, but don't use that option, yet. Update expected test output for the changed error message. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-23-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Rename pragma *-whitelist to *-exceptionsMarkus Armbruster2021-03-234-11/+11
| | | | | | | | | Rename pragma returns-whitelist to command-returns-exceptions, and name-case-whitelist to member-name-case-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-20-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Factor out QAPISchemaParser._check_pragma_list_of_str()Markus Armbruster2021-03-231-10/+9Star
| | | | | | Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-17-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Enforce type naming rulesMarkus Armbruster2021-03-231-1/+2
| | | | | | | | | | Type names should be CamelCase. Enforce this. The only offenders are in tests/. Fix them. Add test type-case to cover the new error. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-15-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Regexp simplified, new test made more robust]
* qapi: Enforce event naming rulesMarkus Armbruster2021-03-231-1/+3
| | | | | | | | | | Event names should be ALL_CAPS with words separated by underscore. Enforce this. The only offenders are in tests/. Fix them. Existing test event-case covers the new error. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-14-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Consistently permit any case in downstream prefixesMarkus Armbruster2021-03-231-1/+1
| | | | | | | | | | We require lowercase __RFQDN_ downstream prefixes only where we require the prefixed name to be lowercase. Don't; permit any case in __RFQDN_ prefixes anywhere. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-13-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Move uppercase rejection to check_name_lower()Markus Armbruster2021-03-231-8/+7Star
| | | | | | | | | | check_name_lower() is the only user of check_name_str() using permit_upper=False. Move the associated code from check_name_str() to check_name_lower(), and drop the parameter. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-12-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Rework name checking in preparation of stricter checkingMarkus Armbruster2021-03-231-15/+36
| | | | | | | | | | | | | | | | | | Naming rules differ for the various kinds of names. To prepare enforcing them, define functions to check them: check_name_upper(), check_name_lower(), and check_name_camel(). For now, these merely wrap around check_name_str(), but that will change shortly. Replace the other uses of check_name_str() by appropriate uses of the wrappers. No change in behavior just yet. check_name_str() now returns the name without downstream and x- prefix, for use by the wrappers in later patches. Requires tweaking regexp @valid_name. It accepts the same strings as before. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-11-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Commit message improved]
* qapi: Lift enum-specific code out of check_name_str()Markus Armbruster2021-03-231-13/+10Star
| | | | | | | | | check_name_str() masks leading digits when passed enum_member=True. Only check_enum() does. Lift the masking into check_enum(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-10-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
* qapi: Permit flat union members for any tag valueMarkus Armbruster2021-03-232-5/+7
| | | | | | | | | | | | | | | | | | | | | | | | Flat union branch names match the tag enum's member names. Omitted branches default to "no members for this tag value". Branch names starting with a digit get rejected like "'data' member '0' has an invalid name". However, omitting the branch works. This is because flat union tag values get checked twice: as enum member name, and as union branch name. The former accepts leading digits, the latter doesn't. Branches whose names start with a digit therefore cannot have members. Feels wrong. Get rid of the restriction by skipping the latter check. This can expose c_name() to input it can't handle: a name starting with a digit. Improve it to return a valid C identifier for any input. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-9-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Commit message rewritten]
* qapi: Fix to reject optional members with reserved namesMarkus Armbruster2021-03-231-5/+4Star
| | | | | | | | | | | | | | | check_type() fails to reject optional members with reserved names, because it neglects to strip off the leading '*'. Fix that. The stripping in check_name_str() is now useless. Drop. Also drop the "no leading '*'" assertion, because valid_name.match() ensures it can't fail. Fixes: 9fb081e0b98409556d023c7193eeb68947cd1211 Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-8-armbru@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com>
* qapi: Implement deprecated-input=reject for QMP command argumentsMarkus Armbruster2021-03-192-2/+4
| | | | | | | | | | | | | | | | | | | | | This policy rejects deprecated input, and thus permits "testing the future". Implement it for QMP command arguments: reject commands with deprecated ones. Example: when QEMU is run with -compat deprecated-input=reject, then {"execute": "eject", "arguments": {"device": "cd"}} fails like this {"error": {"class": "GenericError", "desc": "Deprecated parameter 'device' disabled by policy"}} When the deprecated parameter is removed, the error will change to {"error": {"class": "GenericError", "desc": "Parameter 'device' is unexpected"}} Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20210318155519.1224118-11-armbru@redhat.com>
* qapi: Implement deprecated-input=reject for QMP commandsMarkus Armbruster2021-03-191-3/+7
| | | | | | | | | | | | | | | | | | | | This policy rejects deprecated input, and thus permits "testing the future". Implement it for QMP commands: make deprecated ones fail. Example: when QEMU is run with -compat deprecated-input=reject, then {"execute": "query-cpus"} fails like this {"error": {"class": "CommandNotFound", "desc": "Deprecated command query-cpus disabled by policy"}} When the deprecated command is removed, the error will change to {"error": {"class": "CommandNotFound", "desc": "The command query-cpus has not been found"}} Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20210318155519.1224118-10-armbru@redhat.com>
* qapi: Implement deprecated-output=hide for QMP event dataMarkus Armbruster2021-03-191-3/+6
| | | | | | | | | | | | This policy suppresses deprecated bits in output, and thus permits "testing the future". Implement it for QMP event data: suppress deprecated members. No QMP event data is deprecated right now. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20210318155519.1224118-6-armbru@redhat.com>
* qapi: Implement deprecated-output=hide for QMP eventsMarkus Armbruster2021-03-191-1/+11
| | | | | | | | | | | | This policy suppresses deprecated bits in output, and thus permits "testing the future". Implement it for QMP events: suppress deprecated ones. No QMP event is deprecated right now. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20210318155519.1224118-5-armbru@redhat.com>
* qapi: Implement deprecated-output=hide for QMP command resultsMarkus Armbruster2021-03-192-2/+14
| | | | | | | | | | | | | | | | | | | | | | This policy suppresses deprecated bits in output, and thus permits "testing the future". Implement it for QMP command results. Example: when QEMU is run with -compat deprecated-output=hide, then {"execute": "query-cpus-fast"} yields {"return": [{"thread-id": 9805, "props": {"core-id": 0, "thread-id": 0, "socket-id": 0}, "qom-path": "/machine/unattached/device[0]", "cpu-index": 0, "target": "x86_64"}]} instead of {"return": [{"arch": "x86", "thread-id": 22436, "props": {"core-id": 0, "thread-id": 0, "socket-id": 0}, "qom-path": "/machine/unattached/device[0]", "cpu-index": 0, "target": "x86_64"}]} Note the suppression of deprecated member "arch". Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20210318155519.1224118-4-armbru@redhat.com>
* qapi: Fix parse errors for removal of null from schema languageMarkus Armbruster2021-03-051-4/+4
| | | | | | | | | | Commit 9d55380b5a "qapi: Remove null from schema language" (v4.2.0) neglected to update two error messages. Do that now. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210224101442.1837475-1-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com>
* qapi/introspect.py: set _gen_tree's default ifcond argument to ()John Snow2021-02-181-2/+2
| | | | | | | | | | | We don't need to create an empty, mutable list to pass to _gen_tree; since it is now typed as a Sequence, we can use the empty tuple as a default and omit the argument. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-19-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: Type _gen_tree variants as Sequence[str]John Snow2021-02-181-4/+4
| | | | | | | | | | | | | Optional[List] is clunky; an empty sequence can more elegantly convey "no variants". By downgrading "List" to "Sequence", we can also accept tuples; this is useful for the empty tuple specifically, which we may use as a default parameter because it is immutable. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-18-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Doc string touched up] Reviewed-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: Update copyright and authors listJohn Snow2021-02-181-1/+2
| | | | | | | | | | To reflect the work that went into strictly typing introspect.py, punish myself by claiming credit. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-17-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: Add docstrings to _gen_tree and _tree_to_qlitJohn Snow2021-02-181-0/+20
| | | | | | | | Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-16-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Doc string improvements squashed in] Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: add type hint annotationsJohn Snow2021-02-183-39/+93
| | | | | | | | | | | | | | | | | | | 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/introspect.py: remove _gen_variants helperJohn Snow2021-02-181-7/+2Star
| | | | | | | | | | | | | It is easier to give a name to all of the dictly-typed objects we pass around in introspect.py by removing this helper, as it does not return an object that has any knowable type by itself. Inline it into its only caller instead. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-14-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: improve readability of _tree_to_qlitJohn Snow2021-02-181-15/+18
| | | | | | | | | | | Subjective, but I find getting rid of the comprehensions helps. Also, divide the sections into scalar and non-scalar sections, and remove old-style string formatting. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-13-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: improve _tree_to_qlit error messageJohn Snow2021-02-181-1/+3
| | | | | | | | | | Trivial; make the error message just a pinch more explicit in case we trip this by accident in the future. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-12-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: create a typed 'Annotated' data strutcureJohn Snow2021-02-181-33/+45
| | | | | | | | | | | | | | | | | Presently, we use a tuple to attach a dict containing annotations (comments and compile-time conditionals) to a tree node. This is undesirable because dicts are difficult to strongly type; promoting it to a real class allows us to name the values and types of the annotations we are expecting. In terms of typing, the Annotated<T> type serves as a generic container where the annotated node's type is preserved, allowing for greater specificity than we'd be able to provide without a generic. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-11-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: Introduce preliminary tree typingJohn Snow2021-02-181-1/+30
| | | | | | | | | | | | The types will be used in forthcoming patches to add typing. These types describe the layout and structure of the objects passed to _tree_to_qlit, but lack the power to describe annotations until the next commit. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-10-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: Always define all 'extra' dict keysJohn Snow2021-02-181-5/+4Star
| | | | | | | | | | | | | | | This mimics how a typed object works, where 'if' and 'comment' are always set, regardless of if they have a value set or not. It is safe to do this because of the way that _tree_to_qlit processes these values (using dict.get with a default of None), resulting in no change of output from _tree_to_qlit. There are no other users of this data. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-9-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: replace 'extra' dict with 'comment' argumentJohn Snow2021-02-181-6/+9
| | | | | | | | | | This is only used to pass in a dictionary with a comment already set, so skip the runaround and just accept the (optional) comment. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-8-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: Unify return type of _make_tree()John Snow2021-02-181-3/+1Star
| | | | | | | | | | Returning two different types conditionally can be complicated to type. Return one type for consistency. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-7-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: guard against ifcond/comment misuseJohn Snow2021-02-181-2/+9
| | | | | | | | | | | | | | | | | | _tree_to_qlit is called recursively on dict values (isolated from their keys); at such a point in generating output it is too late to apply an ifcond. Similarly, comments do not necessarily have a "tidy" place they can be printed in such a circumstance. Forbid this usage by renaming "suppress_first_indent" to "dict_value" to emphasize that indents are suppressed only for the benefit of dict values; then add an assertion assuring we do not pass ifcond/comments in this case. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-6-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Comment wrapped to conform to PEP 8] Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: add _gen_features helperJohn Snow2021-02-181-8/+12
| | | | | | | | | | | | _make_tree might receive a dict (a SchemaInfo object) or some other type (usually, a string) for its obj parameter. Adding features information should arguably be performed by the caller at such a time when we know the type of the object and don't have to re-interrogate it. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-5-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
* qapi/introspect.py: use _make_tree for features nodesJohn Snow2021-02-181-1/+3
| | | | | | | | | | | | | | | | | At present, we open-code this in _make_tree itself; but if the structure of the tree changes, this is brittle. Use an explicit recursive call to _make_tree when appropriate to help keep the interior node typing consistent. A consequence of doing this is that the 'ifcond' key of the features dict will be omitted when ifcond is false-ish, just like it is omitted in top-level calls to _make_tree. This also increases consistency in our handling of this property. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210216021809.134886-4-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>