[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 03/16] qapi/expr.py: constrain incoming expression types
From: |
Eduardo Habkost |
Subject: |
Re: [PATCH 03/16] qapi/expr.py: constrain incoming expression types |
Date: |
Wed, 23 Sep 2020 15:42:24 -0400 |
On Tue, Sep 22, 2020 at 05:13:00PM -0400, John Snow wrote:
> 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>
> ---
> scripts/qapi/expr.py | 25 ++++++++++++++++++++++---
> 1 file changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> index 1872a8a3cc..f6b55a87c1 100644
> --- a/scripts/qapi/expr.py
> +++ b/scripts/qapi/expr.py
> @@ -15,9 +15,17 @@
> # See the COPYING file in the top-level directory.
>
> import re
> +from typing import MutableMapping, Optional
>
> from .common import c_name
> from .error import QAPISemError
> +from .parser import QAPIDoc
> +from .source import QAPISourceInfo
> +
> +
> +# Expressions in their raw form are JSON-like structures with arbitrary
> forms.
> +# Minimally, their top-level form must be a mapping of strings to values.
> +Expression = MutableMapping[str, object]
>
>
> # Names must be letters, numbers, -, and _. They must start with letter,
> @@ -280,9 +288,20 @@ def check_event(expr, info):
>
> def check_exprs(exprs):
> for expr_elem in exprs:
> - expr = expr_elem['expr']
> - info = expr_elem['info']
> - doc = expr_elem.get('doc')
> + # Expression
> + assert isinstance(expr_elem['expr'], dict)
> + expr: Expression = expr_elem['expr']
> + for key in expr.keys():
> + assert isinstance(key, str)
mypy doesn't seem to require the key type asserts, on my testing.
> +
> + # 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
Do you need a separate variable here? This seems to work too:
doc = expr_elem.get('doc')
assert doc is None or isinstance(doc, QAPIDoc)
after the assert, mypy will infer the type of doc to be
Optional[QAPIDoc].
None of this should block a useful 120-patch cleanup series, so:
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
>
> if 'include' in expr:
> continue
> --
> 2.26.2
>
--
Eduardo