From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, John Snow <jsnow@redhat.com>
Subject: [PULL 09/13] qapi/parser: add type hint annotations (QAPIDoc)
Date: Sat, 2 Oct 2021 11:56:51 +0200 [thread overview]
Message-ID: <20211002095655.1944970-10-armbru@redhat.com> (raw)
In-Reply-To: <20211002095655.1944970-1-armbru@redhat.com>
From: John Snow <jsnow@redhat.com>
Annotations do not change runtime behavior.
This commit consists of only annotations.
Signed-off-by: John Snow <jsnow@redhat.com>
Message-Id: <20210930205716.1148693-10-jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
scripts/qapi/parser.py | 67 ++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 28 deletions(-)
diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index 75582ddb00..73c1c4ef59 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -37,6 +37,9 @@
from .schema import QAPISchemaFeature, QAPISchemaMember
+#: Represents a single Top Level QAPI schema expression.
+TopLevelExpr = Dict[str, object]
+
# Return value alias for get_expr().
_ExprValue = Union[List[object], Dict[str, object], str, bool]
@@ -454,7 +457,8 @@ class QAPIDoc:
"""
class Section:
- def __init__(self, parser, name=None, indent=0):
+ def __init__(self, parser: QAPISchemaParser,
+ name: Optional[str] = None, indent: int = 0):
# parser, for error messages about indentation
self._parser = parser
# optional section name (argument/member or section name)
@@ -463,7 +467,7 @@ def __init__(self, parser, name=None, indent=0):
# the expected indent level of the text of this section
self._indent = indent
- def append(self, line):
+ def append(self, line: str) -> None:
# Strip leading spaces corresponding to the expected indent level
# Blank lines are always OK.
if line:
@@ -478,7 +482,8 @@ def append(self, line):
self.text += line.rstrip() + '\n'
class ArgSection(Section):
- def __init__(self, parser, name, indent=0):
+ def __init__(self, parser: QAPISchemaParser,
+ name: str, indent: int = 0):
super().__init__(parser, name, indent)
self.member: Optional['QAPISchemaMember'] = None
@@ -489,35 +494,34 @@ class NullSection(Section):
"""
Immutable dummy section for use at the end of a doc block.
"""
- def append(self, line):
+ def append(self, line: str) -> None:
assert False, "Text appended after end_comment() called."
- def __init__(self, parser, info):
+ def __init__(self, parser: QAPISchemaParser, info: QAPISourceInfo):
# self._parser is used to report errors with QAPIParseError. The
# resulting error position depends on the state of the parser.
# It happens to be the beginning of the comment. More or less
# servicable, but action at a distance.
self._parser = parser
self.info = info
- self.symbol = None
+ self.symbol: Optional[str] = None
self.body = QAPIDoc.Section(parser)
- # dict mapping parameter name to ArgSection
- self.args = OrderedDict()
- self.features = OrderedDict()
- # a list of Section
- self.sections = []
+ # dicts mapping parameter/feature names to their ArgSection
+ self.args: Dict[str, QAPIDoc.ArgSection] = OrderedDict()
+ self.features: Dict[str, QAPIDoc.ArgSection] = OrderedDict()
+ self.sections: List[QAPIDoc.Section] = []
# the current section
self._section = self.body
self._append_line = self._append_body_line
- def has_section(self, name):
+ def has_section(self, name: str) -> bool:
"""Return True if we have a section with this name."""
for i in self.sections:
if i.name == name:
return True
return False
- def append(self, line):
+ def append(self, line: str) -> None:
"""
Parse a comment line and add it to the documentation.
@@ -538,18 +542,18 @@ def append(self, line):
line = line[1:]
self._append_line(line)
- def end_comment(self):
+ def end_comment(self) -> None:
self._switch_section(QAPIDoc.NullSection(self._parser))
@staticmethod
- def _is_section_tag(name):
+ def _is_section_tag(name: str) -> bool:
return name in ('Returns:', 'Since:',
# those are often singular or plural
'Note:', 'Notes:',
'Example:', 'Examples:',
'TODO:')
- def _append_body_line(self, line):
+ def _append_body_line(self, line: str) -> None:
"""
Process a line of documentation text in the body section.
@@ -591,7 +595,7 @@ def _append_body_line(self, line):
# This is a free-form documentation block
self._append_freeform(line)
- def _append_args_line(self, line):
+ def _append_args_line(self, line: str) -> None:
"""
Process a line of documentation text in an argument section.
@@ -637,7 +641,7 @@ def _append_args_line(self, line):
self._append_freeform(line)
- def _append_features_line(self, line):
+ def _append_features_line(self, line: str) -> None:
name = line.split(' ', 1)[0]
if name.startswith('@') and name.endswith(':'):
@@ -669,7 +673,7 @@ def _append_features_line(self, line):
self._append_freeform(line)
- def _append_various_line(self, line):
+ def _append_various_line(self, line: str) -> None:
"""
Process a line of documentation text in an additional section.
@@ -705,7 +709,11 @@ def _append_various_line(self, line):
self._append_freeform(line)
- def _start_symbol_section(self, symbols_dict, name, indent):
+ def _start_symbol_section(
+ self,
+ symbols_dict: Dict[str, 'QAPIDoc.ArgSection'],
+ name: str,
+ indent: int) -> None:
# FIXME invalid names other than the empty string aren't flagged
if not name:
raise QAPIParseError(self._parser, "invalid parameter name")
@@ -717,13 +725,14 @@ def _start_symbol_section(self, symbols_dict, name, indent):
self._switch_section(new_section)
symbols_dict[name] = new_section
- def _start_args_section(self, name, indent):
+ def _start_args_section(self, name: str, indent: int) -> None:
self._start_symbol_section(self.args, name, indent)
- def _start_features_section(self, name, indent):
+ def _start_features_section(self, name: str, indent: int) -> None:
self._start_symbol_section(self.features, name, indent)
- def _start_section(self, name=None, indent=0):
+ def _start_section(self, name: Optional[str] = None,
+ indent: int = 0) -> None:
if name in ('Returns', 'Since') and self.has_section(name):
raise QAPIParseError(self._parser,
"duplicated '%s' section" % name)
@@ -731,7 +740,7 @@ def _start_section(self, name=None, indent=0):
self._switch_section(new_section)
self.sections.append(new_section)
- def _switch_section(self, new_section):
+ def _switch_section(self, new_section: 'QAPIDoc.Section') -> None:
text = self._section.text = self._section.text.strip()
# Only the 'body' section is allowed to have an empty body.
@@ -746,7 +755,7 @@ def _switch_section(self, new_section):
self._section = new_section
- def _append_freeform(self, line):
+ def _append_freeform(self, line: str) -> None:
match = re.match(r'(@\S+:)', line)
if match:
raise QAPIParseError(self._parser,
@@ -768,14 +777,16 @@ def connect_feature(self, feature: 'QAPISchemaFeature') -> None:
% feature.name)
self.features[feature.name].connect(feature)
- def check_expr(self, expr):
+ def check_expr(self, expr: TopLevelExpr) -> None:
if self.has_section('Returns') and 'command' not in expr:
raise QAPISemError(self.info,
"'Returns:' is only valid for commands")
- def check(self):
+ def check(self) -> None:
- def check_args_section(args, what):
+ def check_args_section(
+ args: Dict[str, QAPIDoc.ArgSection], what: str
+ ) -> None:
bogus = [name for name, section in args.items()
if not section.member]
if bogus:
--
2.31.1
next prev parent reply other threads:[~2021-10-02 10:07 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-02 9:56 [PULL 00/13] QAPI patches patches for 2021-10-02 Markus Armbruster
2021-10-02 9:56 ` [PULL 01/13] qapi/pylintrc: ignore 'consider-using-f-string' warning Markus Armbruster
2021-10-02 9:56 ` [PULL 02/13] qapi/gen: use dict.items() to iterate over _modules Markus Armbruster
2021-10-02 9:56 ` [PULL 03/13] qapi/parser: fix unused check_args_section arguments Markus Armbruster
2021-10-02 9:56 ` [PULL 04/13] qapi: Add spaces after symbol declaration for consistency Markus Armbruster
2021-10-02 9:56 ` [PULL 05/13] qapi/parser: remove FIXME comment from _append_body_line Markus Armbruster
2021-10-02 9:56 ` [PULL 06/13] qapi/parser: clarify _end_section() logic Markus Armbruster
2021-10-02 9:56 ` [PULL 07/13] qapi/parser: Introduce NullSection Markus Armbruster
2021-10-02 9:56 ` [PULL 08/13] qapi/parser: add import cycle workaround Markus Armbruster
2021-10-02 9:56 ` Markus Armbruster [this message]
2021-10-02 9:56 ` [PULL 10/13] qapi/parser: Add FIXME for consolidating JSON-related types Markus Armbruster
2021-10-02 9:56 ` [PULL 11/13] qapi/parser: enable mypy checks Markus Armbruster
2021-10-02 9:56 ` [PULL 12/13] qapi/parser: Silence too-few-public-methods warning Markus Armbruster
2021-10-02 9:56 ` [PULL 13/13] qapi/parser: enable pylint checks Markus Armbruster
2021-10-02 20:31 ` [PULL 00/13] QAPI patches patches for 2021-10-02 Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211002095655.1944970-10-armbru@redhat.com \
--to=armbru@redhat.com \
--cc=jsnow@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).