qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH RFC 18/32] python//qmp.py: add casts to JSON deserialization


From: Philippe Mathieu-Daudé
Subject: Re: [PATCH RFC 18/32] python//qmp.py: add casts to JSON deserialization
Date: Tue, 26 May 2020 18:03:10 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0

On 5/14/20 7:53 AM, John Snow wrote:
> mypy and python type hints are not powerful enough to properly describe
> JSON messages in Python 3.6. The best we can do, generally, is describe
> them as Dict[str, Any].
> 
> Add casts to coerce this type for static analysis; but do NOT enforce
> this type at runtime in any way.
> 
> Note: Python 3.8 adds a TypedDict construct which allows for the
> description of more arbitrary Dictionary shapes. There is a third-party
> module, "Pydantic", which is compatible with 3.6 that can be used
> instead of the JSON library that parses JSON messages to fully-typed
> Python objects, and may be preferable in some cases.
> 
> (That is well beyond the scope of this commit or series.)
> 
> Signed-off-by: John Snow <address@hidden>
> ---
>  python/qemu/lib/qmp.py | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/python/qemu/lib/qmp.py b/python/qemu/lib/qmp.py
> index 0036204218..e460234f2e 100644
> --- a/python/qemu/lib/qmp.py
> +++ b/python/qemu/lib/qmp.py
> @@ -13,6 +13,7 @@
>  import logging
>  from typing import (
>      Any,
> +    cast,
>      Dict,
>      Optional,
>      TextIO,
> @@ -129,7 +130,10 @@ def __json_read(self, only_event=False):
>              data = self.__sockfile.readline()
>              if not data:
>                  return None
> -            resp = json.loads(data)
> +            # By definition, any JSON received from QMP is a QMPMessage,
> +            # and we are asserting only at static analysis time that it
> +            # has a particular shape.
> +            resp = cast(QMPMessage, json.loads(data))
>              if 'event' in resp:
>                  self.logger.debug("<<< %s", resp)
>                  self.__events.append(resp)
> @@ -261,7 +265,7 @@ def command(self, cmd, **kwds):
>          ret = self.cmd(cmd, kwds)
>          if 'error' in ret:
>              raise QMPResponseError(ret)
> -        return ret['return']
> +        return cast(QMPReturnValue, ret['return'])
>  
>      def pull_event(self, wait=False):
>          """
> 

Acked-by: Philippe Mathieu-Daudé <address@hidden>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]