All of lore.kernel.org
 help / color / mirror / Atom feed
From: Beraldo Leal <bleal@redhat.com>
To: John Snow <jsnow@redhat.com>
Cc: Eduardo Habkost <eduardo@habkost.net>,
	Kevin Wolf <kwolf@redhat.com>,
	Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	Daniel Berrange <berrange@redhat.com>,
	qemu-block@nongnu.org, Markus Armbruster <armbru@redhat.com>,
	qemu-devel@nongnu.org, Wainer Moschetta <wainersm@redhat.com>,
	Andrea Bolognani <abologna@redhat.com>,
	Hanna Reitz <hreitz@redhat.com>,
	Gerd Hoffmann <kraxel@redhat.com>, Cleber Rosa <crosa@redhat.com>
Subject: Re: [PATCH v2 23/25] python: remove the old QMP package
Date: Thu, 16 Dec 2021 11:17:54 -0300	[thread overview]
Message-ID: <20211216141754.zs4lijfo6ibozsme@laptop.redhat> (raw)
In-Reply-To: <20211215193939.3768033-24-jsnow@redhat.com>

On Wed, Dec 15, 2021 at 02:39:37PM -0500, John Snow wrote:
> Thank you for your service!
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  python/PACKAGE.rst          |   4 +-
>  python/README.rst           |   2 +-
>  python/qemu/qmp/README.rst  |   9 -
>  python/qemu/qmp/__init__.py | 396 ------------------------------------
>  python/qemu/qmp/py.typed    |   0
>  python/setup.cfg            |   3 +-
>  6 files changed, 4 insertions(+), 410 deletions(-)
>  delete mode 100644 python/qemu/qmp/README.rst
>  delete mode 100644 python/qemu/qmp/__init__.py
>  delete mode 100644 python/qemu/qmp/py.typed
> 
> diff --git a/python/PACKAGE.rst b/python/PACKAGE.rst
> index b0b86cc4c3..ddfa9ba3f5 100644
> --- a/python/PACKAGE.rst
> +++ b/python/PACKAGE.rst
> @@ -8,11 +8,11 @@ to change at any time.
>  Usage
>  -----
>  
> -The ``qemu.qmp`` subpackage provides a library for communicating with
> +The ``qemu.aqmp`` subpackage provides a library for communicating with
>  QMP servers. The ``qemu.machine`` subpackage offers rudimentary
>  facilities for launching and managing QEMU processes. Refer to each
>  package's documentation
> -(``>>> help(qemu.qmp)``, ``>>> help(qemu.machine)``)
> +(``>>> help(qemu.aqmp)``, ``>>> help(qemu.machine)``)
>  for more information.
>  
>  Contributing
> diff --git a/python/README.rst b/python/README.rst
> index fcf74f69ea..eb5213337d 100644
> --- a/python/README.rst
> +++ b/python/README.rst
> @@ -3,7 +3,7 @@ QEMU Python Tooling
>  
>  This directory houses Python tooling used by the QEMU project to build,
>  configure, and test QEMU. It is organized by namespace (``qemu``), and
> -then by package (e.g. ``qemu/machine``, ``qemu/qmp``, etc).
> +then by package (e.g. ``qemu/machine``, ``qemu/aqmp``, etc).
>  
>  ``setup.py`` is used by ``pip`` to install this tooling to the current
>  environment. ``setup.cfg`` provides the packaging configuration used by
> diff --git a/python/qemu/qmp/README.rst b/python/qemu/qmp/README.rst
> deleted file mode 100644
> index 5bfb82535f..0000000000
> --- a/python/qemu/qmp/README.rst
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -qemu.qmp package
> -================
> -
> -This package provides a library used for connecting to and communicating
> -with QMP servers. It is used extensively by iotests, vm tests,
> -avocado tests, and other utilities in the ./scripts directory. It is
> -not a fully-fledged SDK and is subject to change at any time.
> -
> -See the documentation in ``__init__.py`` for more information.
> diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py
> deleted file mode 100644
> index 4e08641154..0000000000
> --- a/python/qemu/qmp/__init__.py
> +++ /dev/null
> @@ -1,396 +0,0 @@
> -"""
> -QEMU Monitor Protocol (QMP) development library & tooling.
> -
> -This package provides a fairly low-level class for communicating to QMP
> -protocol servers, as implemented by QEMU, the QEMU Guest Agent, and the
> -QEMU Storage Daemon. This library is not intended for production use.
> -
> -`QEMUMonitorProtocol` is the primary class of interest, and all errors
> -raised derive from `QMPError`.
> -"""
> -
> -# Copyright (C) 2009, 2010 Red Hat Inc.
> -#
> -# Authors:
> -#  Luiz Capitulino <lcapitulino@redhat.com>
> -#
> -# This work is licensed under the terms of the GNU GPL, version 2.  See
> -# the COPYING file in the top-level directory.
> -
> -import errno
> -import json
> -import logging
> -import socket
> -import struct
> -from types import TracebackType
> -from typing import (
> -    Any,
> -    Dict,
> -    List,
> -    Optional,
> -    TextIO,
> -    Tuple,
> -    Type,
> -    TypeVar,
> -    Union,
> -    cast,
> -)
> -
> -
> -#: QMPMessage is an entire QMP message of any kind.
> -QMPMessage = Dict[str, Any]
> -
> -#: QMPReturnValue is the 'return' value of a command.
> -QMPReturnValue = object
> -
> -#: QMPObject is any object in a QMP message.
> -QMPObject = Dict[str, object]
> -
> -# QMPMessage can be outgoing commands or incoming events/returns.
> -# QMPReturnValue is usually a dict/json object, but due to QAPI's
> -# 'returns-whitelist', it can actually be anything.
> -#
> -# {'return': {}} is a QMPMessage,
> -# {} is the QMPReturnValue.
> -
> -
> -InternetAddrT = Tuple[str, int]
> -UnixAddrT = str
> -SocketAddrT = Union[InternetAddrT, UnixAddrT]
> -
> -
> -class QMPError(Exception):
> -    """
> -    QMP base exception
> -    """
> -
> -
> -class QMPConnectError(QMPError):
> -    """
> -    QMP connection exception
> -    """
> -
> -
> -class QMPCapabilitiesError(QMPError):
> -    """
> -    QMP negotiate capabilities exception
> -    """
> -
> -
> -class QMPTimeoutError(QMPError):
> -    """
> -    QMP timeout exception
> -    """
> -
> -
> -class QMPProtocolError(QMPError):
> -    """
> -    QMP protocol error; unexpected response
> -    """
> -
> -
> -class QMPResponseError(QMPError):
> -    """
> -    Represents erroneous QMP monitor reply
> -    """
> -    def __init__(self, reply: QMPMessage):
> -        try:
> -            desc = reply['error']['desc']
> -        except KeyError:
> -            desc = reply
> -        super().__init__(desc)
> -        self.reply = reply
> -
> -
> -class QEMUMonitorProtocol:
> -    """
> -    Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP) and then
> -    allow to handle commands and events.
> -    """
> -
> -    #: Logger object for debugging messages
> -    logger = logging.getLogger('QMP')
> -
> -    def __init__(self, address: SocketAddrT,
> -                 server: bool = False,
> -                 nickname: Optional[str] = None):
> -        """
> -        Create a QEMUMonitorProtocol class.
> -
> -        @param address: QEMU address, can be either a unix socket path (string)
> -                        or a tuple in the form ( address, port ) for a TCP
> -                        connection
> -        @param server: server mode listens on the socket (bool)
> -        @raise OSError on socket connection errors
> -        @note No connection is established, this is done by the connect() or
> -              accept() methods
> -        """
> -        self.__events: List[QMPMessage] = []
> -        self.__address = address
> -        self.__sock = self.__get_sock()
> -        self.__sockfile: Optional[TextIO] = None
> -        self._nickname = nickname
> -        if self._nickname:
> -            self.logger = logging.getLogger('QMP').getChild(self._nickname)
> -        if server:
> -            self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
> -            self.__sock.bind(self.__address)
> -            self.__sock.listen(1)
> -
> -    def __get_sock(self) -> socket.socket:
> -        if isinstance(self.__address, tuple):
> -            family = socket.AF_INET
> -        else:
> -            family = socket.AF_UNIX
> -        return socket.socket(family, socket.SOCK_STREAM)
> -
> -    def __negotiate_capabilities(self) -> QMPMessage:
> -        greeting = self.__json_read()
> -        if greeting is None or "QMP" not in greeting:
> -            raise QMPConnectError
> -        # Greeting seems ok, negotiate capabilities
> -        resp = self.cmd('qmp_capabilities')
> -        if resp and "return" in resp:
> -            return greeting
> -        raise QMPCapabilitiesError
> -
> -    def __json_read(self, only_event: bool = False) -> Optional[QMPMessage]:
> -        assert self.__sockfile is not None
> -        while True:
> -            data = self.__sockfile.readline()
> -            if not data:
> -                return None
> -            # 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: QMPMessage = json.loads(data)
> -            if 'event' in resp:
> -                self.logger.debug("<<< %s", resp)
> -                self.__events.append(resp)
> -                if not only_event:
> -                    continue
> -            return resp
> -
> -    def __get_events(self, wait: Union[bool, float] = False) -> None:
> -        """
> -        Check for new events in the stream and cache them in __events.
> -
> -        @param wait (bool): block until an event is available.
> -        @param wait (float): If wait is a float, treat it as a timeout value.
> -
> -        @raise QMPTimeoutError: If a timeout float is provided and the timeout
> -                                period elapses.
> -        @raise QMPConnectError: If wait is True but no events could be
> -                                retrieved or if some other error occurred.
> -        """
> -
> -        # Current timeout and blocking status
> -        current_timeout = self.__sock.gettimeout()
> -
> -        # Check for new events regardless and pull them into the cache:
> -        self.__sock.settimeout(0)  # i.e. setblocking(False)
> -        try:
> -            self.__json_read()
> -        except OSError as err:
> -            # EAGAIN: No data available; not critical
> -            if err.errno != errno.EAGAIN:
> -                raise
> -        finally:
> -            self.__sock.settimeout(current_timeout)
> -
> -        # Wait for new events, if needed.
> -        # if wait is 0.0, this means "no wait" and is also implicitly false.
> -        if not self.__events and wait:
> -            if isinstance(wait, float):
> -                self.__sock.settimeout(wait)
> -            try:
> -                ret = self.__json_read(only_event=True)
> -            except socket.timeout as err:
> -                raise QMPTimeoutError("Timeout waiting for event") from err
> -            except Exception as err:
> -                msg = "Error while reading from socket"
> -                raise QMPConnectError(msg) from err
> -            finally:
> -                self.__sock.settimeout(current_timeout)
> -
> -            if ret is None:
> -                raise QMPConnectError("Error while reading from socket")
> -
> -    T = TypeVar('T')
> -
> -    def __enter__(self: T) -> T:
> -        # Implement context manager enter function.
> -        return self
> -
> -    def __exit__(self,
> -                 # pylint: disable=duplicate-code
> -                 # see https://github.com/PyCQA/pylint/issues/3619
> -                 exc_type: Optional[Type[BaseException]],
> -                 exc_val: Optional[BaseException],
> -                 exc_tb: Optional[TracebackType]) -> None:
> -        # Implement context manager exit function.
> -        self.close()
> -
> -    def connect(self, negotiate: bool = True) -> Optional[QMPMessage]:
> -        """
> -        Connect to the QMP Monitor and perform capabilities negotiation.
> -
> -        @return QMP greeting dict, or None if negotiate is false
> -        @raise OSError on socket connection errors
> -        @raise QMPConnectError if the greeting is not received
> -        @raise QMPCapabilitiesError if fails to negotiate capabilities
> -        """
> -        self.__sock.connect(self.__address)
> -        self.__sockfile = self.__sock.makefile(mode='r')
> -        if negotiate:
> -            return self.__negotiate_capabilities()
> -        return None
> -
> -    def accept(self, timeout: Optional[float] = 15.0) -> QMPMessage:
> -        """
> -        Await connection from QMP Monitor and perform capabilities negotiation.
> -
> -        @param timeout: timeout in seconds (nonnegative float number, or
> -                        None). The value passed will set the behavior of the
> -                        underneath QMP socket as described in [1].
> -                        Default value is set to 15.0.
> -
> -        @return QMP greeting dict
> -        @raise OSError on socket connection errors
> -        @raise QMPConnectError if the greeting is not received
> -        @raise QMPCapabilitiesError if fails to negotiate capabilities
> -
> -        [1]
> -        https://docs.python.org/3/library/socket.html#socket.socket.settimeout
> -        """
> -        self.__sock.settimeout(timeout)
> -        self.__sock, _ = self.__sock.accept()
> -        self.__sockfile = self.__sock.makefile(mode='r')
> -        return self.__negotiate_capabilities()
> -
> -    def cmd_obj(self, qmp_cmd: QMPMessage) -> QMPMessage:
> -        """
> -        Send a QMP command to the QMP Monitor.
> -
> -        @param qmp_cmd: QMP command to be sent as a Python dict
> -        @return QMP response as a Python dict
> -        """
> -        self.logger.debug(">>> %s", qmp_cmd)
> -        self.__sock.sendall(json.dumps(qmp_cmd).encode('utf-8'))
> -        resp = self.__json_read()
> -        if resp is None:
> -            raise QMPConnectError("Unexpected empty reply from server")
> -        self.logger.debug("<<< %s", resp)
> -        return resp
> -
> -    def cmd(self, name: str,
> -            args: Optional[Dict[str, object]] = None,
> -            cmd_id: Optional[object] = None) -> QMPMessage:
> -        """
> -        Build a QMP command and send it to the QMP Monitor.
> -
> -        @param name: command name (string)
> -        @param args: command arguments (dict)
> -        @param cmd_id: command id (dict, list, string or int)
> -        """
> -        qmp_cmd: QMPMessage = {'execute': name}
> -        if args:
> -            qmp_cmd['arguments'] = args
> -        if cmd_id:
> -            qmp_cmd['id'] = cmd_id
> -        return self.cmd_obj(qmp_cmd)
> -
> -    def command(self, cmd: str, **kwds: object) -> QMPReturnValue:
> -        """
> -        Build and send a QMP command to the monitor, report errors if any
> -        """
> -        ret = self.cmd(cmd, kwds)
> -        if 'error' in ret:
> -            raise QMPResponseError(ret)
> -        if 'return' not in ret:
> -            raise QMPProtocolError(
> -                "'return' key not found in QMP response '{}'".format(str(ret))
> -            )
> -        return cast(QMPReturnValue, ret['return'])
> -
> -    def pull_event(self,
> -                   wait: Union[bool, float] = False) -> Optional[QMPMessage]:
> -        """
> -        Pulls a single event.
> -
> -        @param wait (bool): block until an event is available.
> -        @param wait (float): If wait is a float, treat it as a timeout value.
> -
> -        @raise QMPTimeoutError: If a timeout float is provided and the timeout
> -                                period elapses.
> -        @raise QMPConnectError: If wait is True but no events could be
> -                                retrieved or if some other error occurred.
> -
> -        @return The first available QMP event, or None.
> -        """
> -        self.__get_events(wait)
> -
> -        if self.__events:
> -            return self.__events.pop(0)
> -        return None
> -
> -    def get_events(self, wait: bool = False) -> List[QMPMessage]:
> -        """
> -        Get a list of available QMP events and clear all pending events.
> -
> -        @param wait (bool): block until an event is available.
> -        @param wait (float): If wait is a float, treat it as a timeout value.
> -
> -        @raise QMPTimeoutError: If a timeout float is provided and the timeout
> -                                period elapses.
> -        @raise QMPConnectError: If wait is True but no events could be
> -                                retrieved or if some other error occurred.
> -
> -        @return The list of available QMP events.
> -        """
> -        self.__get_events(wait)
> -        events = self.__events
> -        self.__events = []
> -        return events
> -
> -    def clear_events(self) -> None:
> -        """
> -        Clear current list of pending events.
> -        """
> -        self.__events = []
> -
> -    def close(self) -> None:
> -        """
> -        Close the socket and socket file.
> -        """
> -        if self.__sock:
> -            self.__sock.close()
> -        if self.__sockfile:
> -            self.__sockfile.close()
> -
> -    def settimeout(self, timeout: Optional[float]) -> None:
> -        """
> -        Set the socket timeout.
> -
> -        @param timeout (float): timeout in seconds (non-zero), or None.
> -        @note This is a wrap around socket.settimeout
> -
> -        @raise ValueError: if timeout was set to 0.
> -        """
> -        if timeout == 0:
> -            msg = "timeout cannot be 0; this engages non-blocking mode."
> -            msg += " Use 'None' instead to disable timeouts."
> -            raise ValueError(msg)
> -        self.__sock.settimeout(timeout)
> -
> -    def send_fd_scm(self, fd: int) -> None:
> -        """
> -        Send a file descriptor to the remote via SCM_RIGHTS.
> -        """
> -        if self.__sock.family != socket.AF_UNIX:
> -            raise RuntimeError("Can't use SCM_RIGHTS on non-AF_UNIX socket.")
> -
> -        self.__sock.sendmsg(
> -            [b' '],
> -            [(socket.SOL_SOCKET, socket.SCM_RIGHTS, struct.pack('@i', fd))]
> -        )
> diff --git a/python/qemu/qmp/py.typed b/python/qemu/qmp/py.typed
> deleted file mode 100644
> index e69de29bb2..0000000000
> diff --git a/python/setup.cfg b/python/setup.cfg
> index 510df23698..5140a5b322 100644
> --- a/python/setup.cfg
> +++ b/python/setup.cfg
> @@ -24,10 +24,9 @@ classifiers =
>  [options]
>  python_requires = >= 3.6
>  packages =
> -    qemu.qmp
> +    qemu.aqmp
>      qemu.machine
>      qemu.utils
> -    qemu.aqmp
>  
>  [options.package_data]
>  * = py.typed

Reviewed-by: Beraldo Leal <bleal@redhat.com>

--
Beraldo



  parent reply	other threads:[~2021-12-16 14:20 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-15 19:39 [PATCH v2 00/25] Python: delete synchronous qemu.qmp package John Snow
2021-12-15 19:39 ` [PATCH v2 01/25] python/aqmp: add __del__ method to legacy interface John Snow
2021-12-16  9:31   ` Vladimir Sementsov-Ogievskiy
2021-12-16 17:09     ` John Snow
2021-12-16 12:26   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 02/25] python/aqmp: handle asyncio.TimeoutError on execute() John Snow
2021-12-16  9:51   ` Vladimir Sementsov-Ogievskiy
2021-12-16 17:22     ` John Snow
2021-12-16 17:59       ` Vladimir Sementsov-Ogievskiy
2021-12-16 12:39   ` Beraldo Leal
2021-12-16 17:26     ` John Snow
2021-12-15 19:39 ` [PATCH v2 03/25] python/aqmp: copy type definitions from qmp John Snow
2021-12-16 10:00   ` Vladimir Sementsov-Ogievskiy
2021-12-16 10:19   ` Daniel P. Berrangé
2021-12-16 17:31     ` John Snow
2021-12-15 19:39 ` [PATCH v2 04/25] python/aqmp: add SocketAddrT to package root John Snow
2021-12-16 10:01   ` Vladimir Sementsov-Ogievskiy
2021-12-16 13:16   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 05/25] python/aqmp: rename AQMPError to QMPError John Snow
2021-12-16 10:08   ` Vladimir Sementsov-Ogievskiy
2021-12-16 17:01     ` John Snow
2021-12-15 19:39 ` [PATCH v2 06/25] python/qemu-ga-client: update instructions to newer CLI syntax John Snow
2021-12-16 10:14   ` Vladimir Sementsov-Ogievskiy
2021-12-16 17:36     ` John Snow
2021-12-16 10:16   ` Daniel P. Berrangé
2021-12-15 19:39 ` [PATCH v2 07/25] python/qmp: switch qemu-ga-client to AQMP John Snow
2021-12-16 10:31   ` Vladimir Sementsov-Ogievskiy
2021-12-16 17:43     ` John Snow
2021-12-16 13:21   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 08/25] python/qmp: switch qom tools " John Snow
2021-12-16 10:43   ` Vladimir Sementsov-Ogievskiy
2021-12-16 13:26   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 09/25] python/qmp: switch qmp-shell " John Snow
2021-12-16 10:45   ` Vladimir Sementsov-Ogievskiy
2021-12-15 19:39 ` [PATCH v2 10/25] python: move qmp utilities to python/qemu/utils John Snow
2021-12-16 10:48   ` Vladimir Sementsov-Ogievskiy
2021-12-15 19:39 ` [PATCH v2 11/25] python: move qmp-shell under the AQMP package John Snow
2021-12-16 10:49   ` Vladimir Sementsov-Ogievskiy
2021-12-16 13:31   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 12/25] python/machine: permanently switch to AQMP John Snow
2021-12-16 10:51   ` Vladimir Sementsov-Ogievskiy
2021-12-16 17:49     ` John Snow
2021-12-16 13:33   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 13/25] scripts/cpu-x86-uarch-abi: fix CLI parsing John Snow
2021-12-16 10:13   ` Daniel P. Berrangé
2021-12-16 10:55   ` Vladimir Sementsov-Ogievskiy
2021-12-15 19:39 ` [PATCH v2 14/25] scripts/cpu-x86-uarch-abi: switch to AQMP John Snow
2021-12-16 10:14   ` Daniel P. Berrangé
2021-12-16 10:56   ` Vladimir Sementsov-Ogievskiy
2021-12-16 13:46   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 15/25] scripts/render-block-graph: " John Snow
2021-12-16 10:57   ` Vladimir Sementsov-Ogievskiy
2021-12-16 20:48     ` John Snow
2021-12-16 13:47   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 16/25] scripts/bench-block-job: " John Snow
2021-12-16 10:58   ` Vladimir Sementsov-Ogievskiy
2021-12-16 13:49   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 17/25] iotests/mirror-top-perms: " John Snow
2021-12-16 11:01   ` Vladimir Sementsov-Ogievskiy
2021-12-16 13:50   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 18/25] iotests: " John Snow
2021-12-16 11:02   ` Vladimir Sementsov-Ogievskiy
2021-12-16 13:55   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 19/25] python: temporarily silence pylint duplicate-code warnings John Snow
2021-12-16 11:02   ` Vladimir Sementsov-Ogievskiy
2021-12-15 19:39 ` [PATCH v2 20/25] python/aqmp: take QMPBadPortError and parse_address from qemu.qmp John Snow
2021-12-16 11:05   ` Vladimir Sementsov-Ogievskiy
2021-12-16 14:03   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 21/25] python/aqmp: fully separate from qmp.QEMUMonitorProtocol John Snow
2021-12-16 11:11   ` Vladimir Sementsov-Ogievskiy
2021-12-16 14:11   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 22/25] python/aqmp: copy qmp docstrings to qemu.aqmp.legacy John Snow
2021-12-16 11:28   ` Vladimir Sementsov-Ogievskiy
2021-12-16 14:15   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 23/25] python: remove the old QMP package John Snow
2021-12-16 11:30   ` Vladimir Sementsov-Ogievskiy
2021-12-16 14:17   ` Beraldo Leal [this message]
2021-12-15 19:39 ` [PATCH v2 24/25] python: re-enable pylint duplicate-code warnings John Snow
2021-12-16 11:31   ` Vladimir Sementsov-Ogievskiy
2021-12-16 14:18   ` Beraldo Leal
2021-12-15 19:39 ` [PATCH v2 25/25] python: rename qemu.aqmp to qemu.qmp John Snow
2021-12-16 11:41   ` Vladimir Sementsov-Ogievskiy
2021-12-16 21:10     ` John Snow
2021-12-17  7:39       ` Vladimir Sementsov-Ogievskiy
2021-12-17 16:28         ` John Snow
2021-12-16 10:50 ` [PATCH v2 00/25] Python: delete synchronous qemu.qmp package Daniel P. Berrangé
2021-12-16 16:27   ` John Snow

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=20211216141754.zs4lijfo6ibozsme@laptop.redhat \
    --to=bleal@redhat.com \
    --cc=abologna@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=crosa@redhat.com \
    --cc=eduardo@habkost.net \
    --cc=hreitz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    --cc=wainersm@redhat.com \
    /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 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.