All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] qapi: static typing conversion, pt5c
@ 2021-05-20 15:17 John Snow
  2021-05-20 15:17 ` [PATCH 1/3] qapi/expr: Split check_expr out from check_exprs John Snow
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: John Snow @ 2021-05-20 15:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Roth, John Snow, Markus Armbruster

This is part five (c), and focuses on sharing strict types between
parser.py and expr.py.

gitlab: https://gitlab.com/jsnow/qemu/-/commits/python-qapi-cleanup-pt5c

Requirements:
- Python 3.6+
- mypy >= 0.770
- pylint >= 2.6.0 (2.7.0+ when using Python 3.9+)

Every commit should pass with:
 - `isort -c qapi/`
 - `flake8 qapi/`
 - `pylint --rcfile=qapi/pylintrc qapi/`
 - `mypy --config-file=qapi/mypy.ini qapi/`

John Snow (3):
  qapi/expr: Split check_expr out from check_exprs
  qapi/parser.py: add ParsedExpression type
  qapi/parser: Remove _JSONObject

 scripts/qapi/expr.py   | 223 ++++++++++++++++++++---------------------
 scripts/qapi/parser.py |  29 ++++--
 scripts/qapi/schema.py |   6 +-
 3 files changed, 129 insertions(+), 129 deletions(-)

-- 
2.30.2




^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] qapi/expr: Split check_expr out from check_exprs
  2021-05-20 15:17 [PATCH 0/3] qapi: static typing conversion, pt5c John Snow
@ 2021-05-20 15:17 ` John Snow
  2021-05-20 15:17 ` [PATCH 2/3] qapi/parser.py: add ParsedExpression type John Snow
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: John Snow @ 2021-05-20 15:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Roth, John Snow, Markus Armbruster

Primarily, this reduces a nesting level of a particularly long
block. Mostly code movement, a new docstring is created.

(It also has the effect of creating a fairly convenient choke point in
check_exprs for try/catch wrappers without making the nesting level even
worse.)

Signed-off-by: John Snow <jsnow@redhat.com>
---
 scripts/qapi/expr.py | 189 +++++++++++++++++++++++--------------------
 1 file changed, 100 insertions(+), 89 deletions(-)

diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 496f7e0333e..9dff0cd9080 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -586,6 +586,104 @@ def check_event(expr: _JSONObject, info: QAPISourceInfo) -> None:
     check_type(args, info, "'data'", allow_dict=not boxed)
 
 
+def check_expr(expr_elem: _JSONObject) -> None:
+    """
+    Validate and normalize a parsed QAPI schema expression.
+
+    :param expr_elem: The parsed expression to normalize and validate.
+
+    :raise QAPISemError: When this expression fails validation.
+    :return: None, ``expr`` is normalized in-place as needed.
+    """
+    # Expression
+    assert isinstance(expr_elem['expr'], dict)
+    for key in expr_elem['expr'].keys():
+        assert isinstance(key, str)
+    expr: _JSONObject = expr_elem['expr']
+
+    # QAPISourceInfo
+    assert isinstance(expr_elem['info'], QAPISourceInfo)
+    info: QAPISourceInfo = expr_elem['info']
+
+    # Optional[QAPIDoc]
+    tmp = expr_elem.get('doc')
+    assert tmp is None or isinstance(tmp, QAPIDoc)
+    doc: Optional[QAPIDoc] = tmp
+
+    if 'include' in expr:
+        return
+
+    if 'enum' in expr:
+        meta = 'enum'
+    elif 'union' in expr:
+        meta = 'union'
+    elif 'alternate' in expr:
+        meta = 'alternate'
+    elif 'struct' in expr:
+        meta = 'struct'
+    elif 'command' in expr:
+        meta = 'command'
+    elif 'event' in expr:
+        meta = 'event'
+    else:
+        raise QAPISemError(info, "expression is missing metatype")
+
+    check_name_is_str(expr[meta], info, "'%s'" % meta)
+    name = cast(str, expr[meta])
+    info.set_defn(meta, name)
+    check_defn_name_str(name, info, meta)
+
+    if doc:
+        if doc.symbol != name:
+            raise QAPISemError(
+                info, "documentation comment is for '%s'" % doc.symbol)
+        doc.check_expr(expr)
+    elif info.pragma.doc_required:
+        raise QAPISemError(info,
+                           "documentation comment required")
+
+    if meta == 'enum':
+        check_keys(expr, info, meta,
+                   ['enum', 'data'], ['if', 'features', 'prefix'])
+        check_enum(expr, info)
+    elif meta == 'union':
+        check_keys(expr, info, meta,
+                   ['union', 'data'],
+                   ['base', 'discriminator', 'if', 'features'])
+        normalize_members(expr.get('base'))
+        normalize_members(expr['data'])
+        check_union(expr, info)
+    elif meta == 'alternate':
+        check_keys(expr, info, meta,
+                   ['alternate', 'data'], ['if', 'features'])
+        normalize_members(expr['data'])
+        check_alternate(expr, info)
+    elif meta == 'struct':
+        check_keys(expr, info, meta,
+                   ['struct', 'data'], ['base', 'if', 'features'])
+        normalize_members(expr['data'])
+        check_struct(expr, info)
+    elif meta == 'command':
+        check_keys(expr, info, meta,
+                   ['command'],
+                   ['data', 'returns', 'boxed', 'if', 'features',
+                    'gen', 'success-response', 'allow-oob',
+                    'allow-preconfig', 'coroutine'])
+        normalize_members(expr.get('data'))
+        check_command(expr, info)
+    elif meta == 'event':
+        check_keys(expr, info, meta,
+                   ['event'], ['data', 'boxed', 'if', 'features'])
+        normalize_members(expr.get('data'))
+        check_event(expr, info)
+    else:
+        assert False, 'unexpected meta type'
+
+    check_if(expr, info, meta)
+    check_features(expr.get('features'), info)
+    check_flags(expr, info)
+
+
 def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
     """
     Validate and normalize a list of parsed QAPI schema expressions.
@@ -598,93 +696,6 @@ def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
     :raise QAPISemError: When any expression fails validation.
     :return: The same list of expressions (now modified).
     """
-    for expr_elem in exprs:
-        # Expression
-        assert isinstance(expr_elem['expr'], dict)
-        for key in expr_elem['expr'].keys():
-            assert isinstance(key, str)
-        expr: _JSONObject = expr_elem['expr']
-
-        # QAPISourceInfo
-        assert isinstance(expr_elem['info'], QAPISourceInfo)
-        info: QAPISourceInfo = expr_elem['info']
-
-        # Optional[QAPIDoc]
-        tmp = expr_elem.get('doc')
-        assert tmp is None or isinstance(tmp, QAPIDoc)
-        doc: Optional[QAPIDoc] = tmp
-
-        if 'include' in expr:
-            continue
-
-        if 'enum' in expr:
-            meta = 'enum'
-        elif 'union' in expr:
-            meta = 'union'
-        elif 'alternate' in expr:
-            meta = 'alternate'
-        elif 'struct' in expr:
-            meta = 'struct'
-        elif 'command' in expr:
-            meta = 'command'
-        elif 'event' in expr:
-            meta = 'event'
-        else:
-            raise QAPISemError(info, "expression is missing metatype")
-
-        check_name_is_str(expr[meta], info, "'%s'" % meta)
-        name = cast(str, expr[meta])
-        info.set_defn(meta, name)
-        check_defn_name_str(name, info, meta)
-
-        if doc:
-            if doc.symbol != name:
-                raise QAPISemError(
-                    info, "documentation comment is for '%s'" % doc.symbol)
-            doc.check_expr(expr)
-        elif info.pragma.doc_required:
-            raise QAPISemError(info,
-                               "documentation comment required")
-
-        if meta == 'enum':
-            check_keys(expr, info, meta,
-                       ['enum', 'data'], ['if', 'features', 'prefix'])
-            check_enum(expr, info)
-        elif meta == 'union':
-            check_keys(expr, info, meta,
-                       ['union', 'data'],
-                       ['base', 'discriminator', 'if', 'features'])
-            normalize_members(expr.get('base'))
-            normalize_members(expr['data'])
-            check_union(expr, info)
-        elif meta == 'alternate':
-            check_keys(expr, info, meta,
-                       ['alternate', 'data'], ['if', 'features'])
-            normalize_members(expr['data'])
-            check_alternate(expr, info)
-        elif meta == 'struct':
-            check_keys(expr, info, meta,
-                       ['struct', 'data'], ['base', 'if', 'features'])
-            normalize_members(expr['data'])
-            check_struct(expr, info)
-        elif meta == 'command':
-            check_keys(expr, info, meta,
-                       ['command'],
-                       ['data', 'returns', 'boxed', 'if', 'features',
-                        'gen', 'success-response', 'allow-oob',
-                        'allow-preconfig', 'coroutine'])
-            normalize_members(expr.get('data'))
-            check_command(expr, info)
-        elif meta == 'event':
-            check_keys(expr, info, meta,
-                       ['event'], ['data', 'boxed', 'if', 'features'])
-            normalize_members(expr.get('data'))
-            check_event(expr, info)
-        else:
-            assert False, 'unexpected meta type'
-
-        check_if(expr, info, meta)
-        check_features(expr.get('features'), info)
-        check_flags(expr, info)
-
+    for expr in exprs:
+        check_expr(expr)
     return exprs
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] qapi/parser.py: add ParsedExpression type
  2021-05-20 15:17 [PATCH 0/3] qapi: static typing conversion, pt5c John Snow
  2021-05-20 15:17 ` [PATCH 1/3] qapi/expr: Split check_expr out from check_exprs John Snow
@ 2021-05-20 15:17 ` John Snow
  2021-05-20 15:17 ` [PATCH 3/3] qapi/parser: Remove _JSONObject John Snow
  2021-09-08 13:42 ` [PATCH 0/3] qapi: static typing conversion, pt5c Markus Armbruster
  3 siblings, 0 replies; 6+ messages in thread
From: John Snow @ 2021-05-20 15:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Roth, John Snow, Markus Armbruster

This is an immutable, named, typed tuple. It's nicer than arbitrary
dicts for passing data around when using strict typing. We may upgrade
this to a @dataclass style class in the future if we want to support
mutability at a later time. (And after 3.7+ is available for use.)

Turn parser.exprs into a list of ParsedExpressions instead, and adjust
expr.py to match.

This allows the types we specify in parser.py to be remembered all the
way through expr.py and into schema.py. Several assertions around
packing and unpacking this data can be removed as a result.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 scripts/qapi/expr.py   | 29 +++++++++--------------------
 scripts/qapi/parser.py | 29 ++++++++++++++++++-----------
 scripts/qapi/schema.py |  6 +++---
 3 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 9dff0cd9080..6d89343897c 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -44,7 +44,7 @@
 
 from .common import c_name
 from .error import QAPISemError
-from .parser import QAPIDoc
+from .parser import ParsedExpression
 from .source import QAPISourceInfo
 
 
@@ -586,29 +586,17 @@ def check_event(expr: _JSONObject, info: QAPISourceInfo) -> None:
     check_type(args, info, "'data'", allow_dict=not boxed)
 
 
-def check_expr(expr_elem: _JSONObject) -> None:
+def check_expr(pexpr: ParsedExpression) -> None:
     """
-    Validate and normalize a parsed QAPI schema expression.
+    Validate and normalize a `ParsedExpression`.
 
-    :param expr_elem: The parsed expression to normalize and validate.
+    :param pexpr: The parsed expression to normalize and validate.
 
     :raise QAPISemError: When this expression fails validation.
-    :return: None, ``expr`` is normalized in-place as needed.
+    :return: None, ``pexpr`` is normalized in-place as needed.
     """
-    # Expression
-    assert isinstance(expr_elem['expr'], dict)
-    for key in expr_elem['expr'].keys():
-        assert isinstance(key, str)
-    expr: _JSONObject = expr_elem['expr']
-
-    # QAPISourceInfo
-    assert isinstance(expr_elem['info'], QAPISourceInfo)
-    info: QAPISourceInfo = expr_elem['info']
-
-    # Optional[QAPIDoc]
-    tmp = expr_elem.get('doc')
-    assert tmp is None or isinstance(tmp, QAPIDoc)
-    doc: Optional[QAPIDoc] = tmp
+    expr = pexpr.expr
+    info = pexpr.info
 
     if 'include' in expr:
         return
@@ -633,6 +621,7 @@ def check_expr(expr_elem: _JSONObject) -> None:
     info.set_defn(meta, name)
     check_defn_name_str(name, info, meta)
 
+    doc = pexpr.doc
     if doc:
         if doc.symbol != name:
             raise QAPISemError(
@@ -684,7 +673,7 @@ def check_expr(expr_elem: _JSONObject) -> None:
     check_flags(expr, info)
 
 
-def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
+def check_exprs(exprs: List[ParsedExpression]) -> List[ParsedExpression]:
     """
     Validate and normalize a list of parsed QAPI schema expressions.
 
diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index 36d4bd175a0..5ea9b643837 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -21,6 +21,7 @@
     TYPE_CHECKING,
     Dict,
     List,
+    NamedTuple,
     Optional,
     Set,
     Union,
@@ -43,6 +44,12 @@
 _ExprValue = Union[List[object], Dict[str, object], str, bool]
 
 
+class ParsedExpression(NamedTuple):
+    expr: TopLevelExpr
+    info: QAPISourceInfo
+    doc: Optional['QAPIDoc']
+
+
 class QAPIParseError(QAPISourceError):
     """Error class for all QAPI schema parsing errors."""
     def __init__(self, parser: 'QAPISchemaParser', msg: str):
@@ -95,7 +102,7 @@ def __init__(self,
         self.line_pos = 0
 
         # Parser output:
-        self.exprs: List[Dict[str, object]] = []
+        self.exprs: List[ParsedExpression] = []
         self.docs: List[QAPIDoc] = []
 
         # Showtime!
@@ -142,8 +149,7 @@ def _parse(self) -> None:
                                        "value of 'include' must be a string")
                 incl_fname = os.path.join(os.path.dirname(self._fname),
                                           include)
-                self.exprs.append({'expr': {'include': incl_fname},
-                                   'info': info})
+                self._add_expr(OrderedDict({'include': incl_fname}), info)
                 exprs_include = self._include(include, info, incl_fname,
                                               self._included)
                 if exprs_include:
@@ -160,17 +166,18 @@ def _parse(self) -> None:
                 for name, value in pragma.items():
                     self._pragma(name, value, info)
             else:
-                expr_elem = {'expr': expr,
-                             'info': info}
-                if cur_doc:
-                    if not cur_doc.symbol:
-                        raise QAPISemError(
-                            cur_doc.info, "definition documentation required")
-                    expr_elem['doc'] = cur_doc
-                self.exprs.append(expr_elem)
+                if cur_doc and not cur_doc.symbol:
+                    raise QAPISemError(
+                        cur_doc.info, "definition documentation required")
+                self._add_expr(expr, info, cur_doc)
             cur_doc = None
         self.reject_expr_doc(cur_doc)
 
+    def _add_expr(self, expr: TopLevelExpr,
+                  info: QAPISourceInfo,
+                  doc: Optional['QAPIDoc'] = None) -> None:
+        self.exprs.append(ParsedExpression(expr, info, doc))
+
     @staticmethod
     def reject_expr_doc(doc: Optional['QAPIDoc']) -> None:
         if doc and doc.symbol:
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index d1d27ff7ee8..025b22cd3df 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -1148,9 +1148,9 @@ def _def_event(self, expr, info, doc):
 
     def _def_exprs(self, exprs):
         for expr_elem in exprs:
-            expr = expr_elem['expr']
-            info = expr_elem['info']
-            doc = expr_elem.get('doc')
+            expr = expr_elem.expr
+            info = expr_elem.info
+            doc = expr_elem.doc
             if 'enum' in expr:
                 self._def_enum_type(expr, info, doc)
             elif 'struct' in expr:
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] qapi/parser: Remove _JSONObject
  2021-05-20 15:17 [PATCH 0/3] qapi: static typing conversion, pt5c John Snow
  2021-05-20 15:17 ` [PATCH 1/3] qapi/expr: Split check_expr out from check_exprs John Snow
  2021-05-20 15:17 ` [PATCH 2/3] qapi/parser.py: add ParsedExpression type John Snow
@ 2021-05-20 15:17 ` John Snow
  2021-09-08 13:42 ` [PATCH 0/3] qapi: static typing conversion, pt5c Markus Armbruster
  3 siblings, 0 replies; 6+ messages in thread
From: John Snow @ 2021-05-20 15:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Roth, John Snow, Markus Armbruster

Use TopLevelExpr where appropriate now (Any function that accepts
exclusively a Top Level Expression), and replace any other remaining
user with a generic Dict[str, object].

Signed-off-by: John Snow <jsnow@redhat.com>
---
 scripts/qapi/expr.py | 43 ++++++++++++++++++-------------------------
 1 file changed, 18 insertions(+), 25 deletions(-)

diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 6d89343897c..005fbf3a7d8 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -44,18 +44,10 @@
 
 from .common import c_name
 from .error import QAPISemError
-from .parser import ParsedExpression
+from .parser import ParsedExpression, TopLevelExpr
 from .source import QAPISourceInfo
 
 
-# Deserialized JSON objects as returned by the parser.
-# The values of this mapping are not necessary to exhaustively type
-# here (and also not practical as long as mypy lacks recursive
-# types), because the purpose of this module is to interrogate that
-# type.
-_JSONObject = Dict[str, object]
-
-
 # See check_name_str(), below.
 valid_name = re.compile(r'(__[a-z0-9.-]+_)?'
                         r'(x-)?'
@@ -192,7 +184,7 @@ def check_defn_name_str(name: str, info: QAPISourceInfo, meta: str) -> None:
                 info, "%s name should not end in '%s'" % (meta, name[-4:]))
 
 
-def check_keys(value: _JSONObject,
+def check_keys(value: Dict[str, object],
                info: QAPISourceInfo,
                source: str,
                required: Collection[str],
@@ -229,11 +221,11 @@ def pprint(elems: Iterable[str]) -> str:
                pprint(unknown), pprint(allowed)))
 
 
-def check_flags(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_flags(expr: TopLevelExpr, info: QAPISourceInfo) -> None:
     """
     Ensure flag members (if present) have valid values.
 
-    :param expr: The expression to validate.
+    :param expr: The `TopLevelExpr` to validate.
     :param info: QAPI schema source file information.
 
     :raise QAPISemError:
@@ -257,7 +249,8 @@ def check_flags(expr: _JSONObject, info: QAPISourceInfo) -> None:
                                  "are incompatible")
 
 
-def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
+def check_if(expr: Dict[str, object], info: QAPISourceInfo,
+             source: str) -> None:
     """
     Normalize and validate the ``if`` member of an object.
 
@@ -430,9 +423,9 @@ def check_features(features: Optional[object],
         check_if(feat, info, source)
 
 
-def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_enum(expr: TopLevelExpr, info: QAPISourceInfo) -> None:
     """
-    Normalize and validate this expression as an ``enum`` definition.
+    Normalize and validate this `TopLevelExpr` as an ``enum`` definition.
 
     :param expr: The expression to validate.
     :param info: QAPI schema source file information.
@@ -468,9 +461,9 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
         check_if(member, info, source)
 
 
-def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_struct(expr: TopLevelExpr, info: QAPISourceInfo) -> None:
     """
-    Normalize and validate this expression as a ``struct`` definition.
+    Normalize and validate this `TopLevelExpr` as a ``struct`` definition.
 
     :param expr: The expression to validate.
     :param info: QAPI schema source file information.
@@ -485,9 +478,9 @@ def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
     check_type(expr.get('base'), info, "'base'")
 
 
-def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_union(expr: TopLevelExpr, info: QAPISourceInfo) -> None:
     """
-    Normalize and validate this expression as a ``union`` definition.
+    Normalize and validate this `TopLevelExpr` as a ``union`` definition.
 
     :param expr: The expression to validate.
     :param info: QAPI schema source file information.
@@ -522,9 +515,9 @@ def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
         check_type(value['type'], info, source, allow_array=not base)
 
 
-def check_alternate(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_alternate(expr: TopLevelExpr, info: QAPISourceInfo) -> None:
     """
-    Normalize and validate this expression as an ``alternate`` definition.
+    Normalize and validate this `TopLevelExpr` as an ``alternate`` definition.
 
     :param expr: The expression to validate.
     :param info: QAPI schema source file information.
@@ -548,9 +541,9 @@ def check_alternate(expr: _JSONObject, info: QAPISourceInfo) -> None:
         check_type(value['type'], info, source)
 
 
-def check_command(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_command(expr: TopLevelExpr, info: QAPISourceInfo) -> None:
     """
-    Normalize and validate this expression as a ``command`` definition.
+    Normalize and validate this `TopLevelExpr` as a ``command`` definition.
 
     :param expr: The expression to validate.
     :param info: QAPI schema source file information.
@@ -568,9 +561,9 @@ def check_command(expr: _JSONObject, info: QAPISourceInfo) -> None:
     check_type(rets, info, "'returns'", allow_array=True)
 
 
-def check_event(expr: _JSONObject, info: QAPISourceInfo) -> None:
+def check_event(expr: TopLevelExpr, info: QAPISourceInfo) -> None:
     """
-    Normalize and validate this expression as an ``event`` definition.
+    Normalize and validate this `TopLevelExpr` as an ``event`` definition.
 
     :param expr: The expression to validate.
     :param info: QAPI schema source file information.
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] qapi: static typing conversion, pt5c
  2021-05-20 15:17 [PATCH 0/3] qapi: static typing conversion, pt5c John Snow
                   ` (2 preceding siblings ...)
  2021-05-20 15:17 ` [PATCH 3/3] qapi/parser: Remove _JSONObject John Snow
@ 2021-09-08 13:42 ` Markus Armbruster
  2021-09-08 22:21   ` John Snow
  3 siblings, 1 reply; 6+ messages in thread
From: Markus Armbruster @ 2021-09-08 13:42 UTC (permalink / raw)
  To: John Snow; +Cc: Michael Roth, qemu-devel

Needs a rebase now.  Let's finish discussing my review of pt5b [v2]
first.  Pending patches to expr.py should have made it to master by
then.  If you're impatient, suggest to base on master + "[PATCH 0/5]
qapi: Another round of minor fixes and cleanups" + pt5b [v2].



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] qapi: static typing conversion, pt5c
  2021-09-08 13:42 ` [PATCH 0/3] qapi: static typing conversion, pt5c Markus Armbruster
@ 2021-09-08 22:21   ` John Snow
  0 siblings, 0 replies; 6+ messages in thread
From: John Snow @ 2021-09-08 22:21 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: Michael Roth, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 699 bytes --]

On Wed, Sep 8, 2021, 9:42 AM Markus Armbruster <armbru@redhat.com> wrote:

> Needs a rebase now.  Let's finish discussing my review of pt5b [v2]
> first.  Pending patches to expr.py should have made it to master by
> then.  If you're impatient, suggest to base on master + "[PATCH 0/5]
> qapi: Another round of minor fixes and cleanups" + pt5b [v2].
>

Not that impatient. Will focus on seeing 5b through the gates first.

My plan is to get the AQMP stuff merged and CI settled, then return focus
to you. Shouldn't take long.

--js

(ps: trying to answer mails from my phone for $reasons. If my formatting is
garbled and stupid, please just yell at me and I'll figure out how to fix
it. Thanks!)

>

[-- Attachment #2: Type: text/html, Size: 1357 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-09-08 22:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-20 15:17 [PATCH 0/3] qapi: static typing conversion, pt5c John Snow
2021-05-20 15:17 ` [PATCH 1/3] qapi/expr: Split check_expr out from check_exprs John Snow
2021-05-20 15:17 ` [PATCH 2/3] qapi/parser.py: add ParsedExpression type John Snow
2021-05-20 15:17 ` [PATCH 3/3] qapi/parser: Remove _JSONObject John Snow
2021-09-08 13:42 ` [PATCH 0/3] qapi: static typing conversion, pt5c Markus Armbruster
2021-09-08 22:21   ` John Snow

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.