All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] python: create installable package
@ 2020-06-03  0:15 John Snow
  2020-06-03  0:15 ` [PATCH 1/7] python/qemu: create qemu.lib module John Snow
                   ` (8 more replies)
  0 siblings, 9 replies; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

Based-on: 20200602214528.12107-1-jsnow@redhat.com

This series factors the python/qemu directory as an installable
module. As a developer, you can install this to your virtual environment
and then always have access to the classes contained within without
needing to wrangle python import path problems.

When developing, you could go to qemu/python/ and invoke `pipenv shell`
to activate a virtual environment within which you could type `pip
install -e .` to install a special development version of this package
to your virtual environment. This package will always reflect the most
recent version of the source files in the tree.

When not developing, you could install a version of this package to your
environment outright to gain access to the QMP and QEMUMachine classes
for lightweight scripting and testing.

This package is formatted in such a way that it COULD be uploaded to
https://pypi.org/project/qemu and installed independently of qemu.git
with `pip install qemu`, but of course that button remains unpushed.

There are a few major questions to answer first:

- What versioning scheme should we use? See patch 2.

- Should we use a namespace package or not?
  - Namespaced: 'qemu.machine', 'qemu.monitor' etc may be separately
    versioned, packaged and distributed packages. Third party authors
    may register 'qemu.xxx' to create plugins within the namespace as
    they see fit.

  - Non-namespaced: 'qemu' is one giant glob package, packaged and
    versioned in unison. We control this package exclusively.

- How do we eliminate sys.path hacks from the rest of the QEMU tree?
  (Background: sys.path hacks generally impede the function of static
  code quality analysis tools like mypy and pylint.)

  - Simplest: parent scripts (or developer) needs to set PYTHONPATH.

  - Harder: Python scripts should all be written to assume package form,
    all tests and CI that use Python should execute within a VENV.

  In either case, we lose the ability (for many scripts) to "just run" a
  script out of the source tree if it depends on other QEMU Python
  files. This is annoying, but as the complexity of the Python lib
  grows, it is unavoidable.

  In the VENV case, we at least establish a simple paradigm: the scripts
  should work in their "installed" forms; and the rest of the build and
  test infrastructure should use this VENV to automatically handle
  dependencies and path requirements. This should allow us to move many
  of our existing python scripts with "hidden" dependencies into a
  proper python module hierarchy and test for regressions with mypy,
  flake8, pylint, etc.

  (We could even establish e.g. Sphinx versions as a dependency for our
  build kit here and make sure it's installed to the VENV.)

  Pros: Almost all scripts can be moved under python/qemu/* and checked
  with CQA tools. imports are written the same no matter where you are
  (Use the fully qualified names, e.g. qemu.core.qmp.QMPMessage).
  Regressions in scripts are caught *much* faster.

  Downsides: Kind of annoying; most scripts now require you to install a
  devkit forwarder (pip3 install --user .) or be inside of an activated
  venv. Not too bad if you know python at all, but it's certainly less
  plug-n-play.

- What's our backwards compatibility policy if we start shipping this?

  Proposed: Attempt to maintain API compatibility (after stabilizing the
  library). Incompatible changes should probably cause a semver bump.

  Each published release makes no attempt to support any version of QEMU
  other than the one it was released against. We publish this on the tin
  in big red letters.

TESTING THIS PACKAGE OUT:

1. You can install to your local user's environment normally by
navigating to qemu/python/ and typing "pip3 install --user ."

2. If you are in a VENV, use "pip install ."

3. To install in development mode (Where the installed package always
reflects the most recent version of the files automatically), use "pip3
install -e ." or "pip install -e ." as appropriate (See above)

John Snow (7):
  python/qemu: create qemu.lib module
  python/qemu: formalize as package
  python/qemu: add README.rst
  python/qemu: Add pipenv support
  python/qemu: add pylint to pipenv
  python/qemu: Add flake8 to pipenv
  python/qemu: add mypy to pipenv

 python/README.rst                         |   6 +
 python/qemu/README.rst                    |   8 +
 python/Pipfile                            |  14 ++
 python/Pipfile.lock                       | 195 ++++++++++++++++++++++
 python/qemu/__init__.py                   |  11 --
 python/qemu/{ => core}/.flake8            |   0
 python/qemu/core/__init__.py              |  57 +++++++
 python/qemu/{ => core}/accel.py           |   0
 python/qemu/{ => core}/machine.py         |   0
 python/qemu/{ => core}/pylintrc           |   0
 python/qemu/{ => core}/qmp.py             |   0
 python/qemu/{ => core}/qtest.py           |   0
 python/setup.py                           |  50 ++++++
 scripts/device-crash-test                 |   2 +-
 scripts/qmp/qemu-ga-client                |   2 +-
 scripts/qmp/qmp                           |   2 +-
 scripts/qmp/qmp-shell                     |   2 +-
 scripts/qmp/qom-fuse                      |   2 +-
 scripts/qmp/qom-get                       |   2 +-
 scripts/qmp/qom-list                      |   2 +-
 scripts/qmp/qom-set                       |   2 +-
 scripts/qmp/qom-tree                      |   2 +-
 scripts/render_block_graph.py             |   6 +-
 scripts/simplebench/bench_block_job.py    |   4 +-
 tests/acceptance/avocado_qemu/__init__.py |   2 +-
 tests/acceptance/boot_linux.py            |   3 +-
 tests/acceptance/virtio_check_params.py   |   2 +-
 tests/acceptance/virtio_version.py        |   2 +-
 tests/migration/guestperf/engine.py       |   2 +-
 tests/qemu-iotests/235                    |   2 +-
 tests/qemu-iotests/297                    |   2 +-
 tests/qemu-iotests/iotests.py             |   4 +-
 tests/vm/basevm.py                        |   6 +-
 33 files changed, 355 insertions(+), 39 deletions(-)
 create mode 100644 python/README.rst
 create mode 100644 python/qemu/README.rst
 create mode 100644 python/Pipfile
 create mode 100644 python/Pipfile.lock
 delete mode 100644 python/qemu/__init__.py
 rename python/qemu/{ => core}/.flake8 (100%)
 create mode 100644 python/qemu/core/__init__.py
 rename python/qemu/{ => core}/accel.py (100%)
 rename python/qemu/{ => core}/machine.py (100%)
 rename python/qemu/{ => core}/pylintrc (100%)
 rename python/qemu/{ => core}/qmp.py (100%)
 rename python/qemu/{ => core}/qtest.py (100%)
 create mode 100755 python/setup.py

-- 
2.21.3



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

* [PATCH 1/7] python/qemu: create qemu.lib module
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
@ 2020-06-03  0:15 ` John Snow
  2020-06-05 12:33   ` Vladimir Sementsov-Ogievskiy
  2020-06-03  0:15 ` [PATCH 2/7] python/qemu: formalize as package John Snow
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

move python/qemu/*.py to python/qemu/core/*.py.

To create a namespace package, the 'qemu' directory itself shouldn't
have module files in it. Thus, these files will go under a 'lib' package
directory instead.

Bolster the core/__init__.py file a little bit, Make the top-level
classes and functions available directly inside the `qemu.core`
namespace, to facilitate a convenient shorthand:

> from qemu.core import QEMUQtestMachine, QEMUMonitorProtocol

Lastly, update all of the existing import directives.

(Note: these scripts were not necessarily tested to see if they still
work. Some of these scripts are in obvious states of disrepair and it is
beyond the scope of this patch to attempt to fix them.)


RFC: For now, I have used the 'qemu.core' namespace to provide a group
of related tools. I liked Daniel's suggestion of using qemu.machine (and
possible qemu.monitor), but that requires me to rewrite the import
statements and understand a bit more about how to configure
pylint/mypy/flake8 and it's not right to focus on that right now. In the
interest of expedience, I've chosen to keep everything in one package to
be able to send another RFC patchset.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/qemu/__init__.py                   | 11 -----
 python/qemu/{ => core}/.flake8            |  0
 python/qemu/core/__init__.py              | 57 +++++++++++++++++++++++
 python/qemu/{ => core}/accel.py           |  0
 python/qemu/{ => core}/machine.py         |  0
 python/qemu/{ => core}/pylintrc           |  0
 python/qemu/{ => core}/qmp.py             |  0
 python/qemu/{ => core}/qtest.py           |  0
 scripts/device-crash-test                 |  2 +-
 scripts/qmp/qemu-ga-client                |  2 +-
 scripts/qmp/qmp                           |  2 +-
 scripts/qmp/qmp-shell                     |  2 +-
 scripts/qmp/qom-fuse                      |  2 +-
 scripts/qmp/qom-get                       |  2 +-
 scripts/qmp/qom-list                      |  2 +-
 scripts/qmp/qom-set                       |  2 +-
 scripts/qmp/qom-tree                      |  2 +-
 scripts/render_block_graph.py             |  6 +--
 scripts/simplebench/bench_block_job.py    |  4 +-
 tests/acceptance/avocado_qemu/__init__.py |  2 +-
 tests/acceptance/boot_linux.py            |  3 +-
 tests/acceptance/virtio_check_params.py   |  2 +-
 tests/acceptance/virtio_version.py        |  2 +-
 tests/migration/guestperf/engine.py       |  2 +-
 tests/qemu-iotests/235                    |  2 +-
 tests/qemu-iotests/297                    |  2 +-
 tests/qemu-iotests/iotests.py             |  4 +-
 tests/vm/basevm.py                        |  6 +--
 28 files changed, 82 insertions(+), 39 deletions(-)
 delete mode 100644 python/qemu/__init__.py
 rename python/qemu/{ => core}/.flake8 (100%)
 create mode 100644 python/qemu/core/__init__.py
 rename python/qemu/{ => core}/accel.py (100%)
 rename python/qemu/{ => core}/machine.py (100%)
 rename python/qemu/{ => core}/pylintrc (100%)
 rename python/qemu/{ => core}/qmp.py (100%)
 rename python/qemu/{ => core}/qtest.py (100%)

diff --git a/python/qemu/__init__.py b/python/qemu/__init__.py
deleted file mode 100644
index 4ca06c34a41..00000000000
--- a/python/qemu/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# QEMU library
-#
-# Copyright (C) 2015-2016 Red Hat Inc.
-# Copyright (C) 2012 IBM Corp.
-#
-# Authors:
-#  Fam Zheng <famz@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.  See
-# the COPYING file in the top-level directory.
-#
diff --git a/python/qemu/.flake8 b/python/qemu/core/.flake8
similarity index 100%
rename from python/qemu/.flake8
rename to python/qemu/core/.flake8
diff --git a/python/qemu/core/__init__.py b/python/qemu/core/__init__.py
new file mode 100644
index 00000000000..afc587bfdcf
--- /dev/null
+++ b/python/qemu/core/__init__.py
@@ -0,0 +1,57 @@
+"""
+QEMU development and testing library.
+
+This library provides a few high-level classes for driving QEMU from a
+test suite, not intended for production use.
+
+- QEMUMachine: Configure and Boot a QEMU VM
+ - QEMUQtestMachine: VM class, with a qtest socket.
+
+- QEMUMonitorProtocol: Connect to, send/receive QMP messages.
+- QEMUQtestProtocol: Connect to, send/receive qtest message.
+
+- list_accel: List available accelerators
+- kvm_available: Probe for KVM support
+- tcg_available: Probe for TCG support
+"""
+
+# Copyright (C) 2020 John Snow for Red Hat Inc.
+# Copyright (C) 2015-2016 Red Hat Inc.
+# Copyright (C) 2012 IBM Corp.
+#
+# Authors:
+#  John Snow <jsnow@redhat.com>
+#  Fam Zheng <fam@euphon.net>
+#
+# This work is licensed under the terms of the GNU GPL, version 2.  See
+# the COPYING file in the top-level directory.
+#
+
+from .accel import (
+    list_accel,
+    kvm_available,
+    tcg_available,
+)
+
+from .qmp import (
+    QEMUMonitorProtocol,
+)
+
+from .machine import (
+    QEMUMachine,
+)
+
+from .qtest import (
+    QEMUQtestProtocol,
+    QEMUQtestMachine,
+)
+
+__all__ = (
+    'list_accel',
+    'kvm_available',
+    'tcg_available',
+    'QEMUMonitorProtocol',
+    'QEMUMachine',
+    'QEMUQtestProtocol',
+    'QEMUQtestMachine',
+)
diff --git a/python/qemu/accel.py b/python/qemu/core/accel.py
similarity index 100%
rename from python/qemu/accel.py
rename to python/qemu/core/accel.py
diff --git a/python/qemu/machine.py b/python/qemu/core/machine.py
similarity index 100%
rename from python/qemu/machine.py
rename to python/qemu/core/machine.py
diff --git a/python/qemu/pylintrc b/python/qemu/core/pylintrc
similarity index 100%
rename from python/qemu/pylintrc
rename to python/qemu/core/pylintrc
diff --git a/python/qemu/qmp.py b/python/qemu/core/qmp.py
similarity index 100%
rename from python/qemu/qmp.py
rename to python/qemu/core/qmp.py
diff --git a/python/qemu/qtest.py b/python/qemu/core/qtest.py
similarity index 100%
rename from python/qemu/qtest.py
rename to python/qemu/core/qtest.py
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index 305d0427af6..e8f878e7b2f 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -35,7 +35,7 @@ import argparse
 from itertools import chain
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python'))
-from qemu.machine import QEMUMachine
+from qemu.core import QEMUMachine
 
 logger = logging.getLogger('device-crash-test')
 dbg = logger.debug
diff --git a/scripts/qmp/qemu-ga-client b/scripts/qmp/qemu-ga-client
index ce122984a9c..b1e8add6f5d 100755
--- a/scripts/qmp/qemu-ga-client
+++ b/scripts/qmp/qemu-ga-client
@@ -42,7 +42,7 @@ import base64
 import random
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu import qmp
+from qemu.core import qmp
 
 
 class QemuGuestAgent(qmp.QEMUMonitorProtocol):
diff --git a/scripts/qmp/qmp b/scripts/qmp/qmp
index 8e52e4a54de..eaf4b0333aa 100755
--- a/scripts/qmp/qmp
+++ b/scripts/qmp/qmp
@@ -13,7 +13,7 @@
 import sys, os
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import QEMUMonitorProtocol
+from qemu.core import QEMUMonitorProtocol
 
 def print_response(rsp, prefix=[]):
     if type(rsp) == list:
diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index c5eef06f3fd..e819382f68d 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -75,7 +75,7 @@ import atexit
 import re
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu import qmp
+from qemu.core import qmp
 
 class QMPCompleter(list):
     def complete(self, text, state):
diff --git a/scripts/qmp/qom-fuse b/scripts/qmp/qom-fuse
index 5fa6b3bf64d..28f51ec1547 100755
--- a/scripts/qmp/qom-fuse
+++ b/scripts/qmp/qom-fuse
@@ -17,7 +17,7 @@ import os, posix
 from errno import *
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import QEMUMonitorProtocol
+from qemu.core import QEMUMonitorProtocol
 
 fuse.fuse_python_api = (0, 2)
 
diff --git a/scripts/qmp/qom-get b/scripts/qmp/qom-get
index 666df718320..cc97ae09e41 100755
--- a/scripts/qmp/qom-get
+++ b/scripts/qmp/qom-get
@@ -15,7 +15,7 @@ import sys
 import os
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import QEMUMonitorProtocol
+from qemu.core import QEMUMonitorProtocol
 
 cmd, args = sys.argv[0], sys.argv[1:]
 socket_path = None
diff --git a/scripts/qmp/qom-list b/scripts/qmp/qom-list
index 5074fd939f4..2b5e1881b0b 100755
--- a/scripts/qmp/qom-list
+++ b/scripts/qmp/qom-list
@@ -15,7 +15,7 @@ import sys
 import os
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import QEMUMonitorProtocol
+from qemu.core import QEMUMonitorProtocol
 
 cmd, args = sys.argv[0], sys.argv[1:]
 socket_path = None
diff --git a/scripts/qmp/qom-set b/scripts/qmp/qom-set
index 240a78187f9..e001eebe6c4 100755
--- a/scripts/qmp/qom-set
+++ b/scripts/qmp/qom-set
@@ -15,7 +15,7 @@ import sys
 import os
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import QEMUMonitorProtocol
+from qemu.core import QEMUMonitorProtocol
 
 cmd, args = sys.argv[0], sys.argv[1:]
 socket_path = None
diff --git a/scripts/qmp/qom-tree b/scripts/qmp/qom-tree
index 25b0781323c..bd677fd28a0 100755
--- a/scripts/qmp/qom-tree
+++ b/scripts/qmp/qom-tree
@@ -17,7 +17,7 @@ import sys
 import os
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.qmp import QEMUMonitorProtocol
+from qemu.core import QEMUMonitorProtocol
 
 cmd, args = sys.argv[0], sys.argv[1:]
 socket_path = None
diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py
index da6acf050d1..90301f244ba 100755
--- a/scripts/render_block_graph.py
+++ b/scripts/render_block_graph.py
@@ -25,10 +25,8 @@
 from graphviz import Digraph
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python'))
-from qemu.qmp import (
-    QEMUMonitorProtocol,
-    QMPResponseError,
-)
+from qemu.core import QEMUMonitorProtocol
+from qemu.core.machine import MonitorResponseError
 
 
 def perm(arr):
diff --git a/scripts/simplebench/bench_block_job.py b/scripts/simplebench/bench_block_job.py
index 9808d696cfe..9ec5c0a42bb 100755
--- a/scripts/simplebench/bench_block_job.py
+++ b/scripts/simplebench/bench_block_job.py
@@ -25,8 +25,8 @@
 import json
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.machine import QEMUMachine
-from qemu.qmp import QMPConnectError
+from qemu.core import QEMUMachine
+from qemu.core.qmp import QMPConnectError
 
 
 def bench_block_job(cmd, cmd_args, qemu_args):
diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index 77d1c1d9ff1..55e416f7df4 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -32,7 +32,7 @@
 
 sys.path.append(os.path.join(SOURCE_DIR, 'python'))
 
-from qemu.machine import QEMUMachine
+from qemu.core import QEMUMachine
 
 def is_readable_executable_file(path):
     return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
index 3aa57e88b0b..334bc628e80 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/acceptance/boot_linux.py
@@ -12,8 +12,7 @@
 
 from avocado_qemu import Test, BUILD_DIR
 
-from qemu.accel import kvm_available
-from qemu.accel import tcg_available
+from qemu.core import kvm_available, tcg_available
 
 from avocado.utils import cloudinit
 from avocado.utils import network
diff --git a/tests/acceptance/virtio_check_params.py b/tests/acceptance/virtio_check_params.py
index 87e6c839d14..51d9d169cc6 100644
--- a/tests/acceptance/virtio_check_params.py
+++ b/tests/acceptance/virtio_check_params.py
@@ -23,7 +23,7 @@
 import logging
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.machine import QEMUMachine
+from qemu.core import QEMUMachine
 from avocado_qemu import Test
 from avocado import skip
 
diff --git a/tests/acceptance/virtio_version.py b/tests/acceptance/virtio_version.py
index 33593c29dd0..dba149ec4fc 100644
--- a/tests/acceptance/virtio_version.py
+++ b/tests/acceptance/virtio_version.py
@@ -12,7 +12,7 @@
 import os
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.machine import QEMUMachine
+from qemu.core import QEMUMachine
 from avocado_qemu import Test
 
 # Virtio Device IDs:
diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py
index fd63c666015..fef02e157ca 100644
--- a/tests/migration/guestperf/engine.py
+++ b/tests/migration/guestperf/engine.py
@@ -29,7 +29,7 @@
 
 sys.path.append(os.path.join(os.path.dirname(__file__),
                              '..', '..', '..', 'python'))
-from qemu.machine import QEMUMachine
+from qemu.core import QEMUMachine
 
 
 class Engine(object):
diff --git a/tests/qemu-iotests/235 b/tests/qemu-iotests/235
index d1b10ac36bd..4fc4e600414 100755
--- a/tests/qemu-iotests/235
+++ b/tests/qemu-iotests/235
@@ -25,7 +25,7 @@ from iotests import qemu_img_create, qemu_io, file_path, log
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
 
-from qemu.machine import QEMUMachine
+from qemu.core import QEMUMachine
 
 iotests.script_initialize(supported_fmts=['qcow2'])
 
diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
index 5c5420712b1..8236875222d 100755
--- a/tests/qemu-iotests/297
+++ b/tests/qemu-iotests/297
@@ -36,7 +36,7 @@ MYPYPATH=../../python/ mypy --warn-unused-configs --disallow-subclassing-any \
     --disallow-any-generics --disallow-incomplete-defs \
     --disallow-untyped-decorators --no-implicit-optional \
     --warn-redundant-casts --warn-unused-ignores \
-    --no-implicit-reexport iotests.py
+    --no-implicit-reexport --namespace-packages iotests.py
 
 # success, all done
 echo "*** done"
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 19b22bee618..0a6df990f46 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -34,8 +34,8 @@
 
 # pylint: disable=import-error, wrong-import-position
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu import qtest
-from qemu.qmp import QMPMessage
+from qemu.core import qtest
+from qemu.core.qmp import QMPMessage
 
 assert sys.version_info >= (3, 6)
 
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index a80b616a08d..fa5e807689f 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -18,9 +18,6 @@
 import logging
 import time
 import datetime
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.accel import kvm_available
-from qemu.machine import QEMUMachine
 import subprocess
 import hashlib
 import optparse
@@ -30,6 +27,9 @@
 import multiprocessing
 import traceback
 
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
+from qemu.core import kvm_available, QEMUMachine
+
 SSH_KEY = open(os.path.join(os.path.dirname(__file__),
                "..", "keys", "id_rsa")).read()
 SSH_PUB_KEY = open(os.path.join(os.path.dirname(__file__),
-- 
2.21.3



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

* [PATCH 2/7] python/qemu: formalize as package
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
  2020-06-03  0:15 ` [PATCH 1/7] python/qemu: create qemu.lib module John Snow
@ 2020-06-03  0:15 ` John Snow
  2020-06-05 14:40   ` Vladimir Sementsov-Ogievskiy
  2020-06-03  0:15 ` [PATCH 3/7] python/qemu: add README.rst John Snow
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

NB: I am choosing Python 3.6 here. Although our minimum requirement is
3.5, this code is used only by iotests (so far) under which we have been
using a minimum version of 3.6.

3.6 is being preferred here for variable type hint capability, which
enables us to use mypy for this package.

RFC: This uses the version tags of the parent tree here, so packages
will be installed as e.g. 5.0.0, 5.1.0-rc0, etc.

Pros:
 - Easy to tell which versions of QEMU it supports
 - Simple

Cons:
 - Implies semver, which we do NOT follow for QEMU releases
 - Implies the package is in a stable state


We could also start a separate versioning for just the Python SDK at
e.g. 0.1;

Pros:
 - We can use semver, which is expected of Python packaging
 - Allows us to break compatibility for 0.x releases

Cons:
 - More complex, the mapping from SDK version to QEMU version
   is less obvious
 - Requires someone to manage a secondary version commit for
   the Python SDK.

Or, perhaps, we could start versioning with 0.5.0.0, 0.5.1.0, etc to
combine a bit of both flavors; bumping the major version number only
when incompatible changes to the Python interface itself are made,
treating the major version number more like an epoch.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/README.rst |  6 ++++++
 python/setup.py   | 50 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 python/README.rst
 create mode 100755 python/setup.py

diff --git a/python/README.rst b/python/README.rst
new file mode 100644
index 00000000000..25f6d93fd5f
--- /dev/null
+++ b/python/README.rst
@@ -0,0 +1,6 @@
+QEMU Python Tooling
+-------------------
+
+This package provides QEMU tooling used by the QEMU project to build,
+configure, and test QEMU. It is not a fully-fledged SDK and it is subject
+to change at any time.
diff --git a/python/setup.py b/python/setup.py
new file mode 100755
index 00000000000..f897ceac970
--- /dev/null
+++ b/python/setup.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env3 python
+"""
+QEMU tooling installer script
+Copyright (c) 2020 John Snow for Red Hat, Inc.
+"""
+
+import setuptools
+
+def main():
+    """
+    QEMU tooling installer
+    """
+
+    kwargs = {
+        'name': 'qemu',
+        'use_scm_version': {
+            'root': '..',
+            'relative_to': __file__,
+        },
+        'maintainer': 'QEMU Developer Team',
+        'maintainer_email': 'qemu-devel@nongnu.org',
+        'url': 'https://www.qemu.org/',
+        'download_url': 'https://www.qemu.org/download/',
+        'packages': setuptools.find_namespace_packages(),
+        'description': 'QEMU Python Build, Debug and SDK tooling.',
+        'classifiers': [
+            'Development Status :: 5 - Production/Stable',
+            'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
+            'Natural Language :: English',
+            'Operating System :: OS Independent',
+        ],
+        'platforms': [],
+        'keywords': [],
+        'setup_requires': [
+            'setuptools',
+            'setuptools_scm',
+        ],
+        'install_requires': [
+        ],
+        'python_requires': '>=3.6',
+        'long_description_content_type': 'text/x-rst',
+    }
+
+    with open("README.rst", "r") as fh:
+        kwargs['long_description'] = fh.read()
+
+    setuptools.setup(**kwargs)
+
+if __name__ == '__main__':
+    main()
-- 
2.21.3



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

* [PATCH 3/7] python/qemu: add README.rst
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
  2020-06-03  0:15 ` [PATCH 1/7] python/qemu: create qemu.lib module John Snow
  2020-06-03  0:15 ` [PATCH 2/7] python/qemu: formalize as package John Snow
@ 2020-06-03  0:15 ` John Snow
  2020-06-05 14:56   ` Vladimir Sementsov-Ogievskiy
  2020-06-03  0:15 ` [PATCH 4/7] python/qemu: Add pipenv support John Snow
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

Add a short readme that explains the package hierarchy, which will be
visible while browsing the source on e.g. gitlab/github.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/qemu/README.rst | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 python/qemu/README.rst

diff --git a/python/qemu/README.rst b/python/qemu/README.rst
new file mode 100644
index 00000000000..96447b90616
--- /dev/null
+++ b/python/qemu/README.rst
@@ -0,0 +1,8 @@
+python/qemu/
+------------
+
+This directory serves as the root of a `Python PEP 420 implicit
+namespace package <<https://www.python.org/dev/peps/pep-0420/>`_.
+
+Each directory below is assumed to be an installable Python module that
+will be available under the ``qemu.<module>`` namespace.
-- 
2.21.3



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

* [PATCH 4/7] python/qemu: Add pipenv support
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
                   ` (2 preceding siblings ...)
  2020-06-03  0:15 ` [PATCH 3/7] python/qemu: add README.rst John Snow
@ 2020-06-03  0:15 ` John Snow
  2020-06-05 15:37   ` Vladimir Sementsov-Ogievskiy
  2020-06-05 16:21   ` Vladimir Sementsov-Ogievskiy
  2020-06-03  0:15 ` [PATCH 5/7] python/qemu: add pylint to pipenv John Snow
                   ` (4 subsequent siblings)
  8 siblings, 2 replies; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

pipenv is a tool used for managing virtual environments with precisely
specified dependencies. It is separate from the dependencies listed in
setup.py, which are (by 'best practices') not supposed to be pinned.

Note that pipenv is not required to install or use this module; this is
just a convenience for in-tree developing.

Here, a "blank" pipfile is added with no dependencies, but specifies
Python 3.6 for the virtual environment.

Pipfile will specify our version minimums, while Pipfile.lock specifies
an exact loudout of packages that were known to operate correctly. This
latter file provides the real value for easy setup of container images
and CI environments.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/Pipfile | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 python/Pipfile

diff --git a/python/Pipfile b/python/Pipfile
new file mode 100644
index 00000000000..9534830b5eb
--- /dev/null
+++ b/python/Pipfile
@@ -0,0 +1,11 @@
+[[source]]
+name = "pypi"
+url = "https://pypi.org/simple"
+verify_ssl = true
+
+[dev-packages]
+
+[packages]
+
+[requires]
+python_version = "3.6"
-- 
2.21.3



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

* [PATCH 5/7] python/qemu: add pylint to pipenv
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
                   ` (3 preceding siblings ...)
  2020-06-03  0:15 ` [PATCH 4/7] python/qemu: Add pipenv support John Snow
@ 2020-06-03  0:15 ` John Snow
  2020-06-03  0:15 ` [PATCH 6/7] python/qemu: Add flake8 " John Snow
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

A bug in pylint 2.5.1 and 2.5.2 causes false positives for
relative imports. This version is pinned at 2.5.0 until a fix is
available.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/Pipfile      |   1 +
 python/Pipfile.lock | 123 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+)
 create mode 100644 python/Pipfile.lock

diff --git a/python/Pipfile b/python/Pipfile
index 9534830b5eb..ddb2b5a5182 100644
--- a/python/Pipfile
+++ b/python/Pipfile
@@ -4,6 +4,7 @@ url = "https://pypi.org/simple"
 verify_ssl = true
 
 [dev-packages]
+pylint = "==2.5.0"
 
 [packages]
 
diff --git a/python/Pipfile.lock b/python/Pipfile.lock
new file mode 100644
index 00000000000..250f4ebcad7
--- /dev/null
+++ b/python/Pipfile.lock
@@ -0,0 +1,123 @@
+{
+    "_meta": {
+        "hash": {
+            "sha256": "7815dedfd7481b645389153dd45e9adb82c72956d0efc74d8f087497624b75e4"
+        },
+        "pipfile-spec": 6,
+        "requires": {
+            "python_version": "3.6"
+        },
+        "sources": [
+            {
+                "name": "pypi",
+                "url": "https://pypi.org/simple",
+                "verify_ssl": true
+            }
+        ]
+    },
+    "default": {},
+    "develop": {
+        "astroid": {
+            "hashes": [
+                "sha256:4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1",
+                "sha256:d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38"
+            ],
+            "version": "==2.4.1"
+        },
+        "isort": {
+            "hashes": [
+                "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
+                "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"
+            ],
+            "version": "==4.3.21"
+        },
+        "lazy-object-proxy": {
+            "hashes": [
+                "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d",
+                "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449",
+                "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08",
+                "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a",
+                "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50",
+                "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd",
+                "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239",
+                "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb",
+                "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea",
+                "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e",
+                "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156",
+                "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142",
+                "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442",
+                "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62",
+                "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db",
+                "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531",
+                "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383",
+                "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a",
+                "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357",
+                "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4",
+                "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"
+            ],
+            "version": "==1.4.3"
+        },
+        "mccabe": {
+            "hashes": [
+                "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
+                "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
+            ],
+            "version": "==0.6.1"
+        },
+        "pylint": {
+            "hashes": [
+                "sha256:588e114e3f9a1630428c35b7dd1c82c1c93e1b0e78ee312ae4724c5e1a1e0245",
+                "sha256:bd556ba95a4cf55a1fc0004c00cf4560b1e70598a54a74c6904d933c8f3bd5a8"
+            ],
+            "index": "pypi",
+            "version": "==2.5.0"
+        },
+        "six": {
+            "hashes": [
+                "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
+                "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
+            ],
+            "version": "==1.15.0"
+        },
+        "toml": {
+            "hashes": [
+                "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f",
+                "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"
+            ],
+            "version": "==0.10.1"
+        },
+        "typed-ast": {
+            "hashes": [
+                "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
+                "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
+                "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
+                "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
+                "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
+                "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
+                "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
+                "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
+                "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
+                "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
+                "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
+                "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
+                "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
+                "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
+                "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
+                "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
+                "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
+                "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
+                "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
+                "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
+                "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
+            ],
+            "markers": "implementation_name == 'cpython' and python_version < '3.8'",
+            "version": "==1.4.1"
+        },
+        "wrapt": {
+            "hashes": [
+                "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
+            ],
+            "version": "==1.12.1"
+        }
+    }
+}
-- 
2.21.3



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

* [PATCH 6/7] python/qemu: Add flake8 to pipenv
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
                   ` (4 preceding siblings ...)
  2020-06-03  0:15 ` [PATCH 5/7] python/qemu: add pylint to pipenv John Snow
@ 2020-06-03  0:15 ` John Snow
  2020-06-03  0:15 ` [PATCH 7/7] python/qemu: add mypy " John Snow
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

Versions older than 3.6.0 do not appear to work with either pylint 2.5.0
or the type hint syntax in general.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/Pipfile      |  1 +
 python/Pipfile.lock | 39 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/python/Pipfile b/python/Pipfile
index ddb2b5a5182..fc92038ff7a 100644
--- a/python/Pipfile
+++ b/python/Pipfile
@@ -5,6 +5,7 @@ verify_ssl = true
 
 [dev-packages]
 pylint = "==2.5.0"
+flake8 = ">=3.6.0"
 
 [packages]
 
diff --git a/python/Pipfile.lock b/python/Pipfile.lock
index 250f4ebcad7..95b942bd383 100644
--- a/python/Pipfile.lock
+++ b/python/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "7815dedfd7481b645389153dd45e9adb82c72956d0efc74d8f087497624b75e4"
+            "sha256": "30d00455625882e5e23868450487697f75d54474f6912091684d570c5c518c11"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -24,6 +24,22 @@
             ],
             "version": "==2.4.1"
         },
+        "flake8": {
+            "hashes": [
+                "sha256:c69ac1668e434d37a2d2880b3ca9aafd54b3a10a3ac1ab101d22f29e29cf8634",
+                "sha256:ccaa799ef9893cebe69fdfefed76865aeaefbb94cb8545617b2298786a4de9a5"
+            ],
+            "index": "pypi",
+            "version": "==3.8.2"
+        },
+        "importlib-metadata": {
+            "hashes": [
+                "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f",
+                "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"
+            ],
+            "markers": "python_version < '3.8'",
+            "version": "==1.6.0"
+        },
         "isort": {
             "hashes": [
                 "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1",
@@ -64,6 +80,20 @@
             ],
             "version": "==0.6.1"
         },
+        "pycodestyle": {
+            "hashes": [
+                "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367",
+                "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"
+            ],
+            "version": "==2.6.0"
+        },
+        "pyflakes": {
+            "hashes": [
+                "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92",
+                "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"
+            ],
+            "version": "==2.2.0"
+        },
         "pylint": {
             "hashes": [
                 "sha256:588e114e3f9a1630428c35b7dd1c82c1c93e1b0e78ee312ae4724c5e1a1e0245",
@@ -118,6 +148,13 @@
                 "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
             ],
             "version": "==1.12.1"
+        },
+        "zipp": {
+            "hashes": [
+                "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
+                "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
+            ],
+            "version": "==3.1.0"
         }
     }
 }
-- 
2.21.3



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

* [PATCH 7/7] python/qemu: add mypy to pipenv
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
                   ` (5 preceding siblings ...)
  2020-06-03  0:15 ` [PATCH 6/7] python/qemu: Add flake8 " John Snow
@ 2020-06-03  0:15 ` John Snow
  2020-06-06  5:53 ` [PATCH 0/7] python: create installable package Vladimir Sementsov-Ogievskiy
  2020-06-17 19:52 ` Cleber Rosa
  8 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-03  0:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, John Snow, Stefan Hajnoczi,
	Cleber Rosa, Alex Bennée

0.730 appears to be about the oldest version that works with the
features we want, including nice human readable output (to make sure
iotest 297 passes), and type-parameterized Popen generics.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/Pipfile      |  1 +
 python/Pipfile.lock | 37 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/python/Pipfile b/python/Pipfile
index fc92038ff7a..117dd859c57 100644
--- a/python/Pipfile
+++ b/python/Pipfile
@@ -6,6 +6,7 @@ verify_ssl = true
 [dev-packages]
 pylint = "==2.5.0"
 flake8 = ">=3.6.0"
+mypy = ">=0.730"
 
 [packages]
 
diff --git a/python/Pipfile.lock b/python/Pipfile.lock
index 95b942bd383..fe2af682427 100644
--- a/python/Pipfile.lock
+++ b/python/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "30d00455625882e5e23868450487697f75d54474f6912091684d570c5c518c11"
+            "sha256": "773ac04fca007642cbe681368f20b74fea2d74443c14e16d221cb2582344d7bd"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -80,6 +80,33 @@
             ],
             "version": "==0.6.1"
         },
+        "mypy": {
+            "hashes": [
+                "sha256:15b948e1302682e3682f11f50208b726a246ab4e6c1b39f9264a8796bb416aa2",
+                "sha256:219a3116ecd015f8dca7b5d2c366c973509dfb9a8fc97ef044a36e3da66144a1",
+                "sha256:3b1fc683fb204c6b4403a1ef23f0b1fac8e4477091585e0c8c54cbdf7d7bb164",
+                "sha256:3beff56b453b6ef94ecb2996bea101a08f1f8a9771d3cbf4988a61e4d9973761",
+                "sha256:7687f6455ec3ed7649d1ae574136835a4272b65b3ddcf01ab8704ac65616c5ce",
+                "sha256:7ec45a70d40ede1ec7ad7f95b3c94c9cf4c186a32f6bacb1795b60abd2f9ef27",
+                "sha256:86c857510a9b7c3104cf4cde1568f4921762c8f9842e987bc03ed4f160925754",
+                "sha256:8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae",
+                "sha256:8dfb69fbf9f3aeed18afffb15e319ca7f8da9642336348ddd6cab2713ddcf8f9",
+                "sha256:a34b577cdf6313bf24755f7a0e3f3c326d5c1f4fe7422d1d06498eb25ad0c600",
+                "sha256:a8ffcd53cb5dfc131850851cc09f1c44689c2812d0beb954d8138d4f5fc17f65",
+                "sha256:b90928f2d9eb2f33162405f32dde9f6dcead63a0971ca8a1b50eb4ca3e35ceb8",
+                "sha256:c56ffe22faa2e51054c5f7a3bc70a370939c2ed4de308c690e7949230c995913",
+                "sha256:f91c7ae919bbc3f96cd5e5b2e786b2b108343d1d7972ea130f7de27fdd547cf3"
+            ],
+            "index": "pypi",
+            "version": "==0.770"
+        },
+        "mypy-extensions": {
+            "hashes": [
+                "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
+                "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
+            ],
+            "version": "==0.4.3"
+        },
         "pycodestyle": {
             "hashes": [
                 "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367",
@@ -143,6 +170,14 @@
             "markers": "implementation_name == 'cpython' and python_version < '3.8'",
             "version": "==1.4.1"
         },
+        "typing-extensions": {
+            "hashes": [
+                "sha256:6e95524d8a547a91e08f404ae485bbb71962de46967e1b71a0cb89af24e761c5",
+                "sha256:79ee589a3caca649a9bfd2a8de4709837400dfa00b6cc81962a1e6a1815969ae",
+                "sha256:f8d2bd89d25bc39dabe7d23df520442fa1d8969b82544370e03d88b5a591c392"
+            ],
+            "version": "==3.7.4.2"
+        },
         "wrapt": {
             "hashes": [
                 "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"
-- 
2.21.3



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

* Re: [PATCH 1/7] python/qemu: create qemu.lib module
  2020-06-03  0:15 ` [PATCH 1/7] python/qemu: create qemu.lib module John Snow
@ 2020-06-05 12:33   ` Vladimir Sementsov-Ogievskiy
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2020-06-05 12:33 UTC (permalink / raw)
  To: John Snow, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée

03.06.2020 03:15, John Snow wrote:
> move python/qemu/*.py to python/qemu/core/*.py.
> 
> To create a namespace package, the 'qemu' directory itself shouldn't
> have module files in it. Thus, these files will go under a 'lib' package
> directory instead.
> 
> Bolster the core/__init__.py file a little bit, Make the top-level
> classes and functions available directly inside the `qemu.core`
> namespace, to facilitate a convenient shorthand:
> 
>> from qemu.core import QEMUQtestMachine, QEMUMonitorProtocol
> 
> Lastly, update all of the existing import directives.
> 
> (Note: these scripts were not necessarily tested to see if they still
> work. Some of these scripts are in obvious states of disrepair and it is
> beyond the scope of this patch to attempt to fix them.)
> 
> 
> RFC: For now, I have used the 'qemu.core' namespace to provide a group
> of related tools. I liked Daniel's suggestion of using qemu.machine (and
> possible qemu.monitor), but that requires me to rewrite the import
> statements and understand a bit more about how to configure
> pylint/mypy/flake8 and it's not right to focus on that right now. In the
> interest of expedience, I've chosen to keep everything in one package to
> be able to send another RFC patchset.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---

[..]

> --- a/scripts/render_block_graph.py
> +++ b/scripts/render_block_graph.py
> @@ -25,10 +25,8 @@
>   from graphviz import Digraph
>   
>   sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python'))
> -from qemu.qmp import (
> -    QEMUMonitorProtocol,
> -    QMPResponseError,
> -)
> +from qemu.core import QEMUMonitorProtocol
> +from qemu.core.machine import MonitorResponseError

it should be
+from qemu.core.qmp import QMPResponseError

with that fixed:
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>



-- 
Best regards,
Vladimir


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

* Re: [PATCH 2/7] python/qemu: formalize as package
  2020-06-03  0:15 ` [PATCH 2/7] python/qemu: formalize as package John Snow
@ 2020-06-05 14:40   ` Vladimir Sementsov-Ogievskiy
  2020-06-05 15:42     ` John Snow
  2020-06-05 19:23     ` John Snow
  0 siblings, 2 replies; 30+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2020-06-05 14:40 UTC (permalink / raw)
  To: John Snow, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée

03.06.2020 03:15, John Snow wrote:
> NB: I am choosing Python 3.6 here. Although our minimum requirement is
> 3.5, this code is used only by iotests (so far) under which we have been
> using a minimum version of 3.6.
> 
> 3.6 is being preferred here for variable type hint capability, which
> enables us to use mypy for this package.
> 
> RFC: This uses the version tags of the parent tree here, so packages
> will be installed as e.g. 5.0.0, 5.1.0-rc0, etc.
> 
> Pros:
>   - Easy to tell which versions of QEMU it supports
>   - Simple
> 
> Cons:
>   - Implies semver, which we do NOT follow for QEMU releases
>   - Implies the package is in a stable state

Necessarily? Couldn't we state Development Status: Alpha, even with version 5.1.0 ?

> 
> 
> We could also start a separate versioning for just the Python SDK at
> e.g. 0.1;
> 
> Pros:
>   - We can use semver, which is expected of Python packaging
>   - Allows us to break compatibility for 0.x releases
> 
> Cons:
>   - More complex, the mapping from SDK version to QEMU version
>     is less obvious
>   - Requires someone to manage a secondary version commit for
>     the Python SDK.
> 
> Or, perhaps, we could start versioning with 0.5.0.0, 0.5.1.0, etc to
> combine a bit of both flavors; bumping the major version number only
> when incompatible changes to the Python interface itself are made,
> treating the major version number more like an epoch.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   python/README.rst |  6 ++++++
>   python/setup.py   | 50 +++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 56 insertions(+)
>   create mode 100644 python/README.rst
>   create mode 100755 python/setup.py
> 
> diff --git a/python/README.rst b/python/README.rst
> new file mode 100644
> index 00000000000..25f6d93fd5f
> --- /dev/null
> +++ b/python/README.rst
> @@ -0,0 +1,6 @@
> +QEMU Python Tooling
> +-------------------
> +
> +This package provides QEMU tooling used by the QEMU project to build,
> +configure, and test QEMU. It is not a fully-fledged SDK and it is subject
> +to change at any time.
> diff --git a/python/setup.py b/python/setup.py
> new file mode 100755
> index 00000000000..f897ceac970
> --- /dev/null
> +++ b/python/setup.py
> @@ -0,0 +1,50 @@
> +#!/usr/bin/env3 python

env python3 you mean

with it fixed:
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

> +"""
> +QEMU tooling installer script
> +Copyright (c) 2020 John Snow for Red Hat, Inc.
> +"""
> +
> +import setuptools
> +
> +def main():
> +    """
> +    QEMU tooling installer
> +    """
> +
> +    kwargs = {
> +        'name': 'qemu',
> +        'use_scm_version': {
> +            'root': '..',
> +            'relative_to': __file__,
> +        },
> +        'maintainer': 'QEMU Developer Team',
> +        'maintainer_email': 'qemu-devel@nongnu.org',
> +        'url': 'https://www.qemu.org/',
> +        'download_url': 'https://www.qemu.org/download/',
> +        'packages': setuptools.find_namespace_packages(),
> +        'description': 'QEMU Python Build, Debug and SDK tooling.',
> +        'classifiers': [
> +            'Development Status :: 5 - Production/Stable',

Could we use "3 - Alpha" ?

> +            'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
> +            'Natural Language :: English',
> +            'Operating System :: OS Independent',
> +        ],
> +        'platforms': [],
> +        'keywords': [],
> +        'setup_requires': [
> +            'setuptools',
> +            'setuptools_scm',
> +        ],

Hmm, documentation says:

    Warning Using setup_requires is discouraged in favor of PEP-518

did you consider this thing?

> +        'install_requires': [
> +        ],
> +        'python_requires': '>=3.6',
> +        'long_description_content_type': 'text/x-rst',
> +    }
> +
> +    with open("README.rst", "r") as fh:

You use '' for all other strings (except for doc-strings) in this file. Maybe use '' here too?

> +        kwargs['long_description'] = fh.read()
> +
> +    setuptools.setup(**kwargs)
> +
> +if __name__ == '__main__':
> +    main()
> 

Hmm in examples in documentations I always see something like this:

> from setuptools import setup, find_namespace_packages
> 
> setup(
>     name='mynamespace-subpackage-a',
>     ...
>     packages=find_namespace_packages(include=['mynamespace.*'])
> )

How much is it better (or popular) to use __name__ == __main__ style for setup.py?
We are not going to use it as module to import main somewhere...

-- 
Best regards,
Vladimir


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

* Re: [PATCH 3/7] python/qemu: add README.rst
  2020-06-03  0:15 ` [PATCH 3/7] python/qemu: add README.rst John Snow
@ 2020-06-05 14:56   ` Vladimir Sementsov-Ogievskiy
  2020-06-05 16:18     ` John Snow
  0 siblings, 1 reply; 30+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2020-06-05 14:56 UTC (permalink / raw)
  To: John Snow, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée

03.06.2020 03:15, John Snow wrote:
> Add a short readme that explains the package hierarchy, which will be
> visible while browsing the source on e.g. gitlab/github.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   python/qemu/README.rst | 8 ++++++++
>   1 file changed, 8 insertions(+)
>   create mode 100644 python/qemu/README.rst
> 
> diff --git a/python/qemu/README.rst b/python/qemu/README.rst
> new file mode 100644
> index 00000000000..96447b90616
> --- /dev/null
> +++ b/python/qemu/README.rst
> @@ -0,0 +1,8 @@
> +python/qemu/
> +------------
> +
> +This directory serves as the root of a `Python PEP 420 implicit
> +namespace package <<https://www.python.org/dev/peps/pep-0420/>`_.
> +
> +Each directory below is assumed to be an installable Python module that

As far as I understand terminology: s/module/package/

> +will be available under the ``qemu.<module>`` namespace.
> 

and here.

Possibly I'm wrong. anyway:
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

-- 
Best regards,
Vladimir


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

* Re: [PATCH 4/7] python/qemu: Add pipenv support
  2020-06-03  0:15 ` [PATCH 4/7] python/qemu: Add pipenv support John Snow
@ 2020-06-05 15:37   ` Vladimir Sementsov-Ogievskiy
  2020-06-05 15:54     ` John Snow
  2020-06-05 16:21   ` Vladimir Sementsov-Ogievskiy
  1 sibling, 1 reply; 30+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2020-06-05 15:37 UTC (permalink / raw)
  To: John Snow, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée

03.06.2020 03:15, John Snow wrote:
> pipenv is a tool used for managing virtual environments with precisely
> specified dependencies. It is separate from the dependencies listed in
> setup.py, which are (by 'best practices') not supposed to be pinned.
> 
> Note that pipenv is not required to install or use this module; this is
> just a convenience for in-tree developing.
> 
> Here, a "blank" pipfile is added with no dependencies, but specifies
> Python 3.6 for the virtual environment.
> 
> Pipfile will specify our version minimums, while Pipfile.lock specifies
> an exact loudout of packages that were known to operate correctly. This
> latter file provides the real value for easy setup of container images
> and CI environments.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   python/Pipfile | 11 +++++++++++
>   1 file changed, 11 insertions(+)
>   create mode 100644 python/Pipfile
> 
> diff --git a/python/Pipfile b/python/Pipfile
> new file mode 100644
> index 00000000000..9534830b5eb
> --- /dev/null
> +++ b/python/Pipfile
> @@ -0,0 +1,11 @@
> +[[source]]
> +name = "pypi"
> +url = "https://pypi.org/simple"
> +verify_ssl = true

I didn't find what does [[source]] mean, but seems it a standard header of Pipfile.

Not sure, how much sense in it, but:
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

> +
> +[dev-packages]
> +
> +[packages]
> +
> +[requires]
> +python_version = "3.6"
> 


-- 
Best regards,
Vladimir


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

* Re: [PATCH 2/7] python/qemu: formalize as package
  2020-06-05 14:40   ` Vladimir Sementsov-Ogievskiy
@ 2020-06-05 15:42     ` John Snow
  2020-06-05 19:23     ` John Snow
  1 sibling, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-05 15:42 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée



On 6/5/20 10:40 AM, Vladimir Sementsov-Ogievskiy wrote:
> 03.06.2020 03:15, John Snow wrote:
>> NB: I am choosing Python 3.6 here. Although our minimum requirement is
>> 3.5, this code is used only by iotests (so far) under which we have been
>> using a minimum version of 3.6.
>>
>> 3.6 is being preferred here for variable type hint capability, which
>> enables us to use mypy for this package.
>>
>> RFC: This uses the version tags of the parent tree here, so packages
>> will be installed as e.g. 5.0.0, 5.1.0-rc0, etc.
>>
>> Pros:
>>   - Easy to tell which versions of QEMU it supports
>>   - Simple
>>
>> Cons:
>>   - Implies semver, which we do NOT follow for QEMU releases
>>   - Implies the package is in a stable state
> 
> Necessarily? Couldn't we state Development Status: Alpha, even with
> version 5.1.0 ?
> 

It's a good question, actually...

I had thought that the Python packaging ecosystem implied semver, but I
don't see proof of that right now, actually.

PEP440 https://www.python.org/dev/peps/pep-0440/#semantic-versioning
says only that it considers many of the same cases as python versioning
and that it's more prescriptive.

However, in the "Version scheme" section, PEP440 says:

"All numeric components MAY be zero. Except as described below for the
release segment, a numeric component of zero has no special significance
aside from always being the lowest possible value in the version ordering."

I actually don't know what special significance a release segment of 0
has, though -- I don't see that later in the doc.

Semver is described here: https://semver.org/

"Major version zero (0.y.z) is for initial development. Anything MAY
change at any time. The public API SHOULD NOT be considered stable."

I guess we're not beholden to it. Still, it seems common in the Python
world to gate based on major version. It may present packaging
difficulties. I'll try to research more. Maybe I'll reach out to the
PyPI folks and see if I can get advice here.

>>
>>
>> We could also start a separate versioning for just the Python SDK at
>> e.g. 0.1;
>>
>> Pros:
>>   - We can use semver, which is expected of Python packaging
>>   - Allows us to break compatibility for 0.x releases
>>
>> Cons:
>>   - More complex, the mapping from SDK version to QEMU version
>>     is less obvious
>>   - Requires someone to manage a secondary version commit for
>>     the Python SDK.
>>
>> Or, perhaps, we could start versioning with 0.5.0.0, 0.5.1.0, etc to
>> combine a bit of both flavors; bumping the major version number only
>> when incompatible changes to the Python interface itself are made,
>> treating the major version number more like an epoch.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   python/README.rst |  6 ++++++
>>   python/setup.py   | 50 +++++++++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 56 insertions(+)
>>   create mode 100644 python/README.rst
>>   create mode 100755 python/setup.py
>>
>> diff --git a/python/README.rst b/python/README.rst
>> new file mode 100644
>> index 00000000000..25f6d93fd5f
>> --- /dev/null
>> +++ b/python/README.rst
>> @@ -0,0 +1,6 @@
>> +QEMU Python Tooling
>> +-------------------
>> +
>> +This package provides QEMU tooling used by the QEMU project to build,
>> +configure, and test QEMU. It is not a fully-fledged SDK and it is
>> subject
>> +to change at any time.
>> diff --git a/python/setup.py b/python/setup.py
>> new file mode 100755
>> index 00000000000..f897ceac970
>> --- /dev/null
>> +++ b/python/setup.py
>> @@ -0,0 +1,50 @@
>> +#!/usr/bin/env3 python
> 
> env python3 you mean
> 

Oh wow. The funny thing is that it works anyway when you use pip!

> with it fixed:
> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> 
>> +"""
>> +QEMU tooling installer script
>> +Copyright (c) 2020 John Snow for Red Hat, Inc.
>> +"""
>> +
>> +import setuptools
>> +
>> +def main():
>> +    """
>> +    QEMU tooling installer
>> +    """
>> +
>> +    kwargs = {
>> +        'name': 'qemu',
>> +        'use_scm_version': {
>> +            'root': '..',
>> +            'relative_to': __file__,
>> +        },
>> +        'maintainer': 'QEMU Developer Team',
>> +        'maintainer_email': 'qemu-devel@nongnu.org',
>> +        'url': 'https://www.qemu.org/',
>> +        'download_url': 'https://www.qemu.org/download/',
>> +        'packages': setuptools.find_namespace_packages(),
>> +        'description': 'QEMU Python Build, Debug and SDK tooling.',
>> +        'classifiers': [
>> +            'Development Status :: 5 - Production/Stable',
> 
> Could we use "3 - Alpha" ?
> 

Yes. I used 5 for the placeholder package to explain QEMU's stability,
but I should describe the SDK stability instead.

>> +            'License :: OSI Approved :: GNU General Public License v2
>> (GPLv2)',
>> +            'Natural Language :: English',
>> +            'Operating System :: OS Independent',
>> +        ],
>> +        'platforms': [],
>> +        'keywords': [],
>> +        'setup_requires': [
>> +            'setuptools',
>> +            'setuptools_scm',
>> +        ],
> 
> Hmm, documentation says:
> 
>    Warning Using setup_requires is discouraged in favor of PEP-518
> 
> did you consider this thing?
> 

Oh, the TOML thing ... OK, I need to research this more. I tried using
it a few times and I couldn't observe it to be actually working.

It doesn't seem to be in common, widespread usage in the ecosystem yet.

(Also, and I'm serious: it requires a TOML module that isn't built into
Python, so it has some detriments, I think.)

I'll look into this more ardently.

>> +        'install_requires': [
>> +        ],
>> +        'python_requires': '>=3.6',
>> +        'long_description_content_type': 'text/x-rst',
>> +    }
>> +
>> +    with open("README.rst", "r") as fh:
> 
> You use '' for all other strings (except for doc-strings) in this file.
> Maybe use '' here too?
> 

Yes, I should be consistent.

This is not based on any PEP, but I tend to prefer using single quotes
for static strings, and double quotes for format strings -- except when
convenient to deviate for reasons of avoiding backslashes.

>> +        kwargs['long_description'] = fh.read()
>> +
>> +    setuptools.setup(**kwargs)
>> +
>> +if __name__ == '__main__':
>> +    main()
>>
> 
> Hmm in examples in documentations I always see something like this:
> 
>> from setuptools import setup, find_namespace_packages
>>
>> setup(
>>     name='mynamespace-subpackage-a',
>>     ...
>>     packages=find_namespace_packages(include=['mynamespace.*'])
>> )
> 
> How much is it better (or popular) to use __name__ == __main__ style for
> setup.py?
> We are not going to use it as module to import main somewhere...
> 

Mostly just habit. It's not important here, but if you should so happen
to check your setup.py? with pylint, using the __main__ pattern keeps the
check passing.



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

* Re: [PATCH 4/7] python/qemu: Add pipenv support
  2020-06-05 15:37   ` Vladimir Sementsov-Ogievskiy
@ 2020-06-05 15:54     ` John Snow
  0 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-05 15:54 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée



On 6/5/20 11:37 AM, Vladimir Sementsov-Ogievskiy wrote:
> 03.06.2020 03:15, John Snow wrote:
>> pipenv is a tool used for managing virtual environments with precisely
>> specified dependencies. It is separate from the dependencies listed in
>> setup.py, which are (by 'best practices') not supposed to be pinned.
>>
>> Note that pipenv is not required to install or use this module; this is
>> just a convenience for in-tree developing.
>>
>> Here, a "blank" pipfile is added with no dependencies, but specifies
>> Python 3.6 for the virtual environment.
>>
>> Pipfile will specify our version minimums, while Pipfile.lock specifies
>> an exact loudout of packages that were known to operate correctly. This
>> latter file provides the real value for easy setup of container images
>> and CI environments.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   python/Pipfile | 11 +++++++++++
>>   1 file changed, 11 insertions(+)
>>   create mode 100644 python/Pipfile
>>
>> diff --git a/python/Pipfile b/python/Pipfile
>> new file mode 100644
>> index 00000000000..9534830b5eb
>> --- /dev/null
>> +++ b/python/Pipfile
>> @@ -0,0 +1,11 @@
>> +[[source]]
>> +name = "pypi"
>> +url = "https://pypi.org/simple"
>> +verify_ssl = true
> 
> I didn't find what does [[source]] mean, but seems it a standard header
> of Pipfile.
> 
> Not sure, how much sense in it, but:
> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> 

Yeah, this is generated by the pipenv tool. I assume this describes
which repositories should be probed for downloading packages.

--js



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

* Re: [PATCH 3/7] python/qemu: add README.rst
  2020-06-05 14:56   ` Vladimir Sementsov-Ogievskiy
@ 2020-06-05 16:18     ` John Snow
  0 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-05 16:18 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée



On 6/5/20 10:56 AM, Vladimir Sementsov-Ogievskiy wrote:
> 03.06.2020 03:15, John Snow wrote:
>> Add a short readme that explains the package hierarchy, which will be
>> visible while browsing the source on e.g. gitlab/github.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   python/qemu/README.rst | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>   create mode 100644 python/qemu/README.rst
>>
>> diff --git a/python/qemu/README.rst b/python/qemu/README.rst
>> new file mode 100644
>> index 00000000000..96447b90616
>> --- /dev/null
>> +++ b/python/qemu/README.rst
>> @@ -0,0 +1,8 @@
>> +python/qemu/
>> +------------
>> +
>> +This directory serves as the root of a `Python PEP 420 implicit
>> +namespace package <<https://www.python.org/dev/peps/pep-0420/>`_.
>> +
>> +Each directory below is assumed to be an installable Python module that
> 
> As far as I understand terminology: s/module/package/
> 
>> +will be available under the ``qemu.<module>`` namespace.
>>
> 
> and here.
> 
> Possibly I'm wrong. anyway:
> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> 

Oh, you're right. Each file is a module, each folder is a package. Thank
you for spotting that.



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

* Re: [PATCH 4/7] python/qemu: Add pipenv support
  2020-06-03  0:15 ` [PATCH 4/7] python/qemu: Add pipenv support John Snow
  2020-06-05 15:37   ` Vladimir Sementsov-Ogievskiy
@ 2020-06-05 16:21   ` Vladimir Sementsov-Ogievskiy
  2020-06-05 17:11     ` John Snow
  1 sibling, 1 reply; 30+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2020-06-05 16:21 UTC (permalink / raw)
  To: John Snow, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée

03.06.2020 03:15, John Snow wrote:
> pipenv is a tool used for managing virtual environments with precisely
> specified dependencies. It is separate from the dependencies listed in
> setup.py, which are (by 'best practices') not supposed to be pinned.
> 
> Note that pipenv is not required to install or use this module; this is
> just a convenience for in-tree developing.
> 
> Here, a "blank" pipfile is added with no dependencies, but specifies
> Python 3.6 for the virtual environment.
> 
> Pipfile will specify our version minimums, while Pipfile.lock specifies
> an exact loudout of packages that were known to operate correctly. This
> latter file provides the real value for easy setup of container images
> and CI environments.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   python/Pipfile | 11 +++++++++++
>   1 file changed, 11 insertions(+)
>   create mode 100644 python/Pipfile
> 
> diff --git a/python/Pipfile b/python/Pipfile
> new file mode 100644
> index 00000000000..9534830b5eb
> --- /dev/null
> +++ b/python/Pipfile
> @@ -0,0 +1,11 @@
> +[[source]]
> +name = "pypi"
> +url = "https://pypi.org/simple"
> +verify_ssl = true
> +
> +[dev-packages]
> +
> +[packages]
> +
> +[requires]
> +python_version = "3.6"
> 

Should it be >= or something like this?

And, how should I use this all?

My failed attempt:
[root@kvm python]# pipenv install --python /usr/bin/python3
Virtualenv already exists!
Removing existing virtualenv…
Creating a virtualenv for this project…
Pipfile: /work/src/qemu/john-python-installable/python/Pipfile
Using /usr/bin/python3 (3.7.5) to create virtualenv…
⠹ Creating virtual environment...created virtual environment CPython3.7.5.final.0-64 in 112ms
   creator CPython3Posix(dest=/root/.local/share/virtualenvs/python-4FwBBPCc, clear=False, global=False)
   seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, via=copy, app_data_dir=/root/.local/share/virtualenv/seed-app-data/v1.0.1)
   activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

✔ Successfully created virtual environment!
Virtualenv location: /root/.local/share/virtualenvs/python-4FwBBPCc
Warning: Your Pipfile requires python_version 3.6, but you are using 3.7.5 (/root/.local/share/v/p/bin/python).
   $ pipenv --rm and rebuilding the virtual environment may resolve the issue.
   $ pipenv check will surely fail.
Installing dependencies from Pipfile.lock (44d7bd)…
   🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
[root@kvm python]# pipenv shell
Warning: Your Pipfile requires python_version 3.6, but you are using 3.7.5 (/root/.local/share/v/p/bin/python).
   $ pipenv --rm and rebuilding the virtual environment may resolve the issue.
   $ pipenv check will surely fail.
Launching subshell in virtual environment…
  . /root/.local/share/virtualenvs/python-4FwBBPCc/bin/activate
[root@kvm work]#  . /root/.local/share/virtualenvs/python-4FwBBPCc/bin/activate
(python) [root@kvm work]# python
Python 3.7.5 (default, Oct 17 2019, 12:09:47)
[GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pylint
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'pylint'
>>> 

and iotest 297 says: "pylint-3 not found"

(honestly, I'm new to using python virtual environment)

-- 
Best regards,
Vladimir


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

* Re: [PATCH 4/7] python/qemu: Add pipenv support
  2020-06-05 16:21   ` Vladimir Sementsov-Ogievskiy
@ 2020-06-05 17:11     ` John Snow
  2020-06-06  5:31       ` Vladimir Sementsov-Ogievskiy
  0 siblings, 1 reply; 30+ messages in thread
From: John Snow @ 2020-06-05 17:11 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée



On 6/5/20 12:21 PM, Vladimir Sementsov-Ogievskiy wrote:
> 03.06.2020 03:15, John Snow wrote:
>> pipenv is a tool used for managing virtual environments with precisely
>> specified dependencies. It is separate from the dependencies listed in
>> setup.py, which are (by 'best practices') not supposed to be pinned.
>>
>> Note that pipenv is not required to install or use this module; this is
>> just a convenience for in-tree developing.
>>
>> Here, a "blank" pipfile is added with no dependencies, but specifies
>> Python 3.6 for the virtual environment.
>>
>> Pipfile will specify our version minimums, while Pipfile.lock specifies
>> an exact loudout of packages that were known to operate correctly. This
>> latter file provides the real value for easy setup of container images
>> and CI environments.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   python/Pipfile | 11 +++++++++++
>>   1 file changed, 11 insertions(+)
>>   create mode 100644 python/Pipfile
>>
>> diff --git a/python/Pipfile b/python/Pipfile
>> new file mode 100644
>> index 00000000000..9534830b5eb
>> --- /dev/null
>> +++ b/python/Pipfile
>> @@ -0,0 +1,11 @@
>> +[[source]]
>> +name = "pypi"
>> +url = "https://pypi.org/simple"
>> +verify_ssl = true
>> +
>> +[dev-packages]
>> +
>> +[packages]
>> +
>> +[requires]
>> +python_version = "3.6"
>>
> 
> Should it be >= or something like this?
> 

I think logistically that makes sense, but I'm not sure if the tool
supports it.

I decided to target the oldest version of Python we support (for
non-build infrastructure) to ensure a minimum viability.

> And, how should I use this all?
> 
> My failed attempt:
> [root@kvm python]# pipenv install --python /usr/bin/python3
> Virtualenv already exists!
> Removing existing virtualenv…
> Creating a virtualenv for this project…
> Pipfile: /work/src/qemu/john-python-installable/python/Pipfile
> Using /usr/bin/python3 (3.7.5) to create virtualenv…
> ⠹ Creating virtual environment...created virtual environment
> CPython3.7.5.final.0-64 in 112ms
>   creator
> CPython3Posix(dest=/root/.local/share/virtualenvs/python-4FwBBPCc,
> clear=False, global=False)
>   seeder FromAppData(download=False, pip=latest, setuptools=latest,
> wheel=latest, via=copy,
> app_data_dir=/root/.local/share/virtualenv/seed-app-data/v1.0.1)
>   activators
> BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
> 
> 
> ✔ Successfully created virtual environment!
> Virtualenv location: /root/.local/share/virtualenvs/python-4FwBBPCc
> Warning: Your Pipfile requires python_version 3.6, but you are using
> 3.7.5 (/root/.local/share/v/p/bin/python).
>   $ pipenv --rm and rebuilding the virtual environment may resolve the
> issue.
>   $ pipenv check will surely fail.
> Installing dependencies from Pipfile.lock (44d7bd)…
>   🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
> To activate this project's virtualenv, run pipenv shell.
> Alternatively, run a command inside the virtualenv with pipenv run.
> [root@kvm python]# pipenv shell
> Warning: Your Pipfile requires python_version 3.6, but you are using
> 3.7.5 (/root/.local/share/v/p/bin/python).
>   $ pipenv --rm and rebuilding the virtual environment may resolve the
> issue.
>   $ pipenv check will surely fail.
> Launching subshell in virtual environment…
>  . /root/.local/share/virtualenvs/python-4FwBBPCc/bin/activate
> [root@kvm work]#  .
> /root/.local/share/virtualenvs/python-4FwBBPCc/bin/activate
> (python) [root@kvm work]# python
> Python 3.7.5 (default, Oct 17 2019, 12:09:47)
> [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> import pylint
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ModuleNotFoundError: No module named 'pylint'
>>>>
> 
> and iotest 297 says: "pylint-3 not found"
> 

Ah! that's a bug in iotest 297. It's expecting the fedora package there.
I'll have to fix that.

> (honestly, I'm new to using python virtual environment)
> 

Good questions. I'll document this in the README.rst for this folder,
actually...



1. Create a virtual environment

> pipenv sync --dev

jsnow@probe ~/s/q/python (python-package-refactor)> pipenv sync --dev
Creating a virtualenv for this project…
Pipfile: /home/jsnow/src/qemu/python/Pipfile
Using /usr/bin/python3.6 (3.6.10) to create virtualenv…
⠏ Creating virtual environment...Using base prefix '/usr'
New python executable in
/home/jsnow/.local/share/virtualenvs/python-QepCANQl/bin/python3.6
Also creating executable in
/home/jsnow/.local/share/virtualenvs/python-QepCANQl/bin/python
Installing setuptools, pip, wheel...done.
Running virtualenv with interpreter /usr/bin/python3.6

✔ Successfully created virtual environment!
Virtualenv location: /home/jsnow/.local/share/virtualenvs/python-QepCANQl
Installing dependencies from Pipfile.lock (44d7bd)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 17/17 — 00:00:07
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
All dependencies are now up-to-date!


This command can both create and synchronize the venv's packages with
those listed in Pipfile.lock.

It may be helpful to know that Pipfile describes which packages, with
coarse version requirements. Pipfile.lock describes EXACTLY which
package versions to install.

Pipenv, therefore, is a way to produce consistent execution environments
in which we can run tests that are the same for everybody.

When we want to update our packages for this repeatable environment, we
can use 'pipenv update' and commit the Pipfile.lock changes back to git.

(Note, using --dev here installs the development dependencies. If you
omit it, you won't get any packages installed, because there are no
runtime dependencies for this package!)


2. Where did it create the venv?

jsnow@probe ~/s/q/python (python-package-refactor)> pipenv --venv
/home/jsnow/.local/share/virtualenvs/python-QepCANQl


3. Entering the venv

jsnow@probe ~/s/q/python (python-package-refactor)> pipenv shell
Launching subshell in virtual environment…
Welcome to fish, the friendly interactive shell
jsnow@probe ~/s/q/python (python-package-refactor)>  source
/home/jsnow/.local/share/virtualenvs/python-QepCANQl/bin/activate.fish

(python) jsnow@probe ~/s/q/python (python-package-refactor)>

 ^^^^^^ the virtual environment I am in

                     my git branch ^^^^^^^^^^^^^^^^^^^^^^^


This just automates opening a sub-shell and then sourcing the activation
file for you. You can do it manually if you'd like.


4. Installing the QEMU package in development mode to the venv

So far, pipenv only installed our development requirements. Install the
package itself.

From inside `pipenv shell`:

> pip install -e .
Obtaining file:///home/jsnow/src/qemu/python
Installing collected packages: qemu
  Running setup.py develop for qemu
Successfully installed qemu

Or, if you are outside the venv:

> pipenv run pip install -e .


5. Using the qemu package

(From inside the venv)

(python) jsnow@probe ~/s/q/python (python-package-refactor)> python3
Python 3.6.10 (default, Dec 27 2019, 13:40:13)
[GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import qemu.core
>>> dir(qemu.core)
['QEMUMachine', 'QEMUMonitorProtocol', 'QEMUQtestMachine',
'QEMUQtestProtocol', '__all__', '__builtins__', '__cached__', '__doc__',
'__file__', '__loader__', '__name__', '__package__', '__path__',
'__spec__', 'accel', 'kvm_available', 'list_accel', 'machine', 'qmp',
'qtest', 'tcg_available']
>>>



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

* Re: [PATCH 2/7] python/qemu: formalize as package
  2020-06-05 14:40   ` Vladimir Sementsov-Ogievskiy
  2020-06-05 15:42     ` John Snow
@ 2020-06-05 19:23     ` John Snow
  1 sibling, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-05 19:23 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée



On 6/5/20 10:40 AM, Vladimir Sementsov-Ogievskiy wrote:
> 
> Hmm, documentation says:
> 
>    Warning Using setup_requires is discouraged in favor of PEP-518
> 
> did you consider this thing?

I guess the difference here is we start using a pyproject.toml and then
we declare setuptools, wheel and setuptools_scm dependencies there.

In turn, pip will no longer install those projects to the user's
environment, but will create its own virtual environment for the
purposes of the build/installation process.

(It looks like pip re-downloads and re-installs these files every time
you run the install? That seems ... bad?)

It looks like this support was added in pip 10. Not all the platforms we
support at the moment appear to have pip 10 in their distribution
repository, though technically ... you could use pip 9 to install a more
modern pip to your userspace.

I think maybe I'd prefer to just leave this alone for now. We can update
it if there's some compelling reason to upgrade, but it's still a pretty
new feature that doesn't seem to be in widespread usage yet.

setuptools is widely regarded to be "the default", and I believe pip
will assume and support this for a while longer yet.

No hurry to upgrade, I think, but I could be wrong. Python packaging is
convoluted.

--js



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

* Re: [PATCH 4/7] python/qemu: Add pipenv support
  2020-06-05 17:11     ` John Snow
@ 2020-06-06  5:31       ` Vladimir Sementsov-Ogievskiy
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2020-06-06  5:31 UTC (permalink / raw)
  To: John Snow, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée

05.06.2020 20:11, John Snow wrote:
> 
> 
> On 6/5/20 12:21 PM, Vladimir Sementsov-Ogievskiy wrote:
>> 03.06.2020 03:15, John Snow wrote:
>>> pipenv is a tool used for managing virtual environments with precisely
>>> specified dependencies. It is separate from the dependencies listed in
>>> setup.py, which are (by 'best practices') not supposed to be pinned.
>>>
>>> Note that pipenv is not required to install or use this module; this is
>>> just a convenience for in-tree developing.
>>>
>>> Here, a "blank" pipfile is added with no dependencies, but specifies
>>> Python 3.6 for the virtual environment.
>>>
>>> Pipfile will specify our version minimums, while Pipfile.lock specifies
>>> an exact loudout of packages that were known to operate correctly. This
>>> latter file provides the real value for easy setup of container images
>>> and CI environments.
>>>
>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>> ---
>>>    python/Pipfile | 11 +++++++++++
>>>    1 file changed, 11 insertions(+)
>>>    create mode 100644 python/Pipfile
>>>
>>> diff --git a/python/Pipfile b/python/Pipfile
>>> new file mode 100644
>>> index 00000000000..9534830b5eb
>>> --- /dev/null
>>> +++ b/python/Pipfile
>>> @@ -0,0 +1,11 @@
>>> +[[source]]
>>> +name = "pypi"
>>> +url = "https://pypi.org/simple"
>>> +verify_ssl = true
>>> +
>>> +[dev-packages]
>>> +
>>> +[packages]
>>> +
>>> +[requires]
>>> +python_version = "3.6"
>>>
>>
>> Should it be >= or something like this?
>>
> 
> I think logistically that makes sense, but I'm not sure if the tool
> supports it.
> 
> I decided to target the oldest version of Python we support (for
> non-build infrastructure) to ensure a minimum viability.
> 
>> And, how should I use this all?
>>
>> My failed attempt:
>> [root@kvm python]# pipenv install --python /usr/bin/python3
>> Virtualenv already exists!
>> Removing existing virtualenv…
>> Creating a virtualenv for this project…
>> Pipfile: /work/src/qemu/john-python-installable/python/Pipfile
>> Using /usr/bin/python3 (3.7.5) to create virtualenv…
>> ⠹ Creating virtual environment...created virtual environment
>> CPython3.7.5.final.0-64 in 112ms
>>    creator
>> CPython3Posix(dest=/root/.local/share/virtualenvs/python-4FwBBPCc,
>> clear=False, global=False)
>>    seeder FromAppData(download=False, pip=latest, setuptools=latest,
>> wheel=latest, via=copy,
>> app_data_dir=/root/.local/share/virtualenv/seed-app-data/v1.0.1)
>>    activators
>> BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
>>
>>
>> ✔ Successfully created virtual environment!
>> Virtualenv location: /root/.local/share/virtualenvs/python-4FwBBPCc
>> Warning: Your Pipfile requires python_version 3.6, but you are using
>> 3.7.5 (/root/.local/share/v/p/bin/python).
>>    $ pipenv --rm and rebuilding the virtual environment may resolve the
>> issue.
>>    $ pipenv check will surely fail.
>> Installing dependencies from Pipfile.lock (44d7bd)…
>>    🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
>> To activate this project's virtualenv, run pipenv shell.
>> Alternatively, run a command inside the virtualenv with pipenv run.
>> [root@kvm python]# pipenv shell
>> Warning: Your Pipfile requires python_version 3.6, but you are using
>> 3.7.5 (/root/.local/share/v/p/bin/python).
>>    $ pipenv --rm and rebuilding the virtual environment may resolve the
>> issue.
>>    $ pipenv check will surely fail.
>> Launching subshell in virtual environment…
>>   . /root/.local/share/virtualenvs/python-4FwBBPCc/bin/activate
>> [root@kvm work]#  .
>> /root/.local/share/virtualenvs/python-4FwBBPCc/bin/activate
>> (python) [root@kvm work]# python
>> Python 3.7.5 (default, Oct 17 2019, 12:09:47)
>> [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>> import pylint
>> Traceback (most recent call last):
>>    File "<stdin>", line 1, in <module>
>> ModuleNotFoundError: No module named 'pylint'
>>>>>
>>
>> and iotest 297 says: "pylint-3 not found"
>>
> 
> Ah! that's a bug in iotest 297. It's expecting the fedora package there.
> I'll have to fix that.
> 
>> (honestly, I'm new to using python virtual environment)
>>
> 
> Good questions. I'll document this in the README.rst for this folder,
> actually...
> 
> 
> 
> 1. Create a virtual environment
> 
>> pipenv sync --dev
> 
> jsnow@probe ~/s/q/python (python-package-refactor)> pipenv sync --dev
> Creating a virtualenv for this project…
> Pipfile: /home/jsnow/src/qemu/python/Pipfile
> Using /usr/bin/python3.6 (3.6.10) to create virtualenv…
> ⠏ Creating virtual environment...Using base prefix '/usr'
> New python executable in
> /home/jsnow/.local/share/virtualenvs/python-QepCANQl/bin/python3.6
> Also creating executable in
> /home/jsnow/.local/share/virtualenvs/python-QepCANQl/bin/python
> Installing setuptools, pip, wheel...done.
> Running virtualenv with interpreter /usr/bin/python3.6
> 
> ✔ Successfully created virtual environment!
> Virtualenv location: /home/jsnow/.local/share/virtualenvs/python-QepCANQl
> Installing dependencies from Pipfile.lock (44d7bd)…
>    🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 17/17 — 00:00:07
> To activate this project's virtualenv, run pipenv shell.
> Alternatively, run a command inside the virtualenv with pipenv run.
> All dependencies are now up-to-date!
> 
> 
> This command can both create and synchronize the venv's packages with
> those listed in Pipfile.lock.
> 
> It may be helpful to know that Pipfile describes which packages, with
> coarse version requirements. Pipfile.lock describes EXACTLY which
> package versions to install.
> 
> Pipenv, therefore, is a way to produce consistent execution environments
> in which we can run tests that are the same for everybody.
> 
> When we want to update our packages for this repeatable environment, we
> can use 'pipenv update' and commit the Pipfile.lock changes back to git.
> 
> (Note, using --dev here installs the development dependencies. If you
> omit it, you won't get any packages installed, because there are no
> runtime dependencies for this package!)

Seems, that was my mistake, now it works, thanks!

> 
> 
> 2. Where did it create the venv?
> 
> jsnow@probe ~/s/q/python (python-package-refactor)> pipenv --venv
> /home/jsnow/.local/share/virtualenvs/python-QepCANQl
> 
> 
> 3. Entering the venv
> 
> jsnow@probe ~/s/q/python (python-package-refactor)> pipenv shell
> Launching subshell in virtual environment…
> Welcome to fish, the friendly interactive shell
> jsnow@probe ~/s/q/python (python-package-refactor)>  source
> /home/jsnow/.local/share/virtualenvs/python-QepCANQl/bin/activate.fish
> 
> (python) jsnow@probe ~/s/q/python (python-package-refactor)>
> 
>   ^^^^^^ the virtual environment I am in
> 
>                       my git branch ^^^^^^^^^^^^^^^^^^^^^^^
> 
> 
> This just automates opening a sub-shell and then sourcing the activation
> file for you. You can do it manually if you'd like.
> 
> 
> 4. Installing the QEMU package in development mode to the venv
> 
> So far, pipenv only installed our development requirements. Install the
> package itself.
> 
>  From inside `pipenv shell`:
> 
>> pip install -e .
> Obtaining file:///home/jsnow/src/qemu/python
> Installing collected packages: qemu
>    Running setup.py develop for qemu
> Successfully installed qemu
> 
> Or, if you are outside the venv:
> 
>> pipenv run pip install -e .
> 
> 
> 5. Using the qemu package
> 
> (From inside the venv)
> 
> (python) jsnow@probe ~/s/q/python (python-package-refactor)> python3
> Python 3.6.10 (default, Dec 27 2019, 13:40:13)
> [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> import qemu.core
>>>> dir(qemu.core)
> ['QEMUMachine', 'QEMUMonitorProtocol', 'QEMUQtestMachine',
> 'QEMUQtestProtocol', '__all__', '__builtins__', '__cached__', '__doc__',
> '__file__', '__loader__', '__name__', '__package__', '__path__',
> '__spec__', 'accel', 'kvm_available', 'list_accel', 'machine', 'qmp',
> 'qtest', 'tcg_available']
>>>>
> 


-- 
Best regards,
Vladimir


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

* Re: [PATCH 0/7] python: create installable package
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
                   ` (6 preceding siblings ...)
  2020-06-03  0:15 ` [PATCH 7/7] python/qemu: add mypy " John Snow
@ 2020-06-06  5:53 ` Vladimir Sementsov-Ogievskiy
  2020-06-08 14:14   ` John Snow
  2020-06-17 19:52 ` Cleber Rosa
  8 siblings, 1 reply; 30+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2020-06-06  5:53 UTC (permalink / raw)
  To: John Snow, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée

For patches 05-07:

Reviewing such patch is a strange thing: Pipfile changes are obvious enough, just select some version (I can't be sure about correct version choice, just believe in your commit messages). But what for Pipfile.lock? I can state that it's about package set selecting, Pipfile.lock looks like what it should be, but I have idea about all these packages, their versions and hashes (and even, does it correspond really to Pipfile or not) :)

Ha, what I can check, is: does pipenv create almost same Pipfile.lock in my environment (with 3.7.5 python)
OK, I've tried (pipenv lock --dev --python /usr/bin/python3), and yes, result is almost the same. For mypy and importlib-metadata packages I have newer version and different hashes (of course). Other packages are the same. Set of packages is the same.

Hmm, but in may generated Pipfile.lock there no "markers". They are about python version and looks like "markers": "python_version >= '3.5'".. Does pipenv follow them? Then why they are not generated for me, did you use some additional command/option to create them?
Anyway, they don't look dangerous, so for last three patches:
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

03.06.2020 03:15, John Snow wrote:
> Based-on: 20200602214528.12107-1-jsnow@redhat.com
> 
> This series factors the python/qemu directory as an installable
> module. As a developer, you can install this to your virtual environment
> and then always have access to the classes contained within without
> needing to wrangle python import path problems.
> 
> When developing, you could go to qemu/python/ and invoke `pipenv shell`
> to activate a virtual environment within which you could type `pip
> install -e .` to install a special development version of this package
> to your virtual environment. This package will always reflect the most
> recent version of the source files in the tree.
> 
> When not developing, you could install a version of this package to your
> environment outright to gain access to the QMP and QEMUMachine classes
> for lightweight scripting and testing.
> 
> This package is formatted in such a way that it COULD be uploaded to
> https://pypi.org/project/qemu and installed independently of qemu.git
> with `pip install qemu`, but of course that button remains unpushed.
> 
> There are a few major questions to answer first:
> 
> - What versioning scheme should we use? See patch 2.
> 
> - Should we use a namespace package or not?
>    - Namespaced: 'qemu.machine', 'qemu.monitor' etc may be separately
>      versioned, packaged and distributed packages. Third party authors
>      may register 'qemu.xxx' to create plugins within the namespace as
>      they see fit.
> 
>    - Non-namespaced: 'qemu' is one giant glob package, packaged and
>      versioned in unison. We control this package exclusively.
> 
> - How do we eliminate sys.path hacks from the rest of the QEMU tree?
>    (Background: sys.path hacks generally impede the function of static
>    code quality analysis tools like mypy and pylint.)
> 
>    - Simplest: parent scripts (or developer) needs to set PYTHONPATH.
> 
>    - Harder: Python scripts should all be written to assume package form,
>      all tests and CI that use Python should execute within a VENV.
> 
>    In either case, we lose the ability (for many scripts) to "just run" a
>    script out of the source tree if it depends on other QEMU Python
>    files. This is annoying, but as the complexity of the Python lib
>    grows, it is unavoidable.
> 
>    In the VENV case, we at least establish a simple paradigm: the scripts
>    should work in their "installed" forms; and the rest of the build and
>    test infrastructure should use this VENV to automatically handle
>    dependencies and path requirements. This should allow us to move many
>    of our existing python scripts with "hidden" dependencies into a
>    proper python module hierarchy and test for regressions with mypy,
>    flake8, pylint, etc.
> 
>    (We could even establish e.g. Sphinx versions as a dependency for our
>    build kit here and make sure it's installed to the VENV.)
> 
>    Pros: Almost all scripts can be moved under python/qemu/* and checked
>    with CQA tools. imports are written the same no matter where you are
>    (Use the fully qualified names, e.g. qemu.core.qmp.QMPMessage).
>    Regressions in scripts are caught *much* faster.
> 
>    Downsides: Kind of annoying; most scripts now require you to install a
>    devkit forwarder (pip3 install --user .) or be inside of an activated
>    venv. Not too bad if you know python at all, but it's certainly less
>    plug-n-play.
> 
> - What's our backwards compatibility policy if we start shipping this?
> 
>    Proposed: Attempt to maintain API compatibility (after stabilizing the
>    library). Incompatible changes should probably cause a semver bump.
> 
>    Each published release makes no attempt to support any version of QEMU
>    other than the one it was released against. We publish this on the tin
>    in big red letters.
> 
> TESTING THIS PACKAGE OUT:
> 
> 1. You can install to your local user's environment normally by
> navigating to qemu/python/ and typing "pip3 install --user ."
> 
> 2. If you are in a VENV, use "pip install ."
> 
> 3. To install in development mode (Where the installed package always
> reflects the most recent version of the files automatically), use "pip3
> install -e ." or "pip install -e ." as appropriate (See above)
> 
> John Snow (7):
>    python/qemu: create qemu.lib module
>    python/qemu: formalize as package
>    python/qemu: add README.rst
>    python/qemu: Add pipenv support
>    python/qemu: add pylint to pipenv
>    python/qemu: Add flake8 to pipenv
>    python/qemu: add mypy to pipenv
> 
>   python/README.rst                         |   6 +
>   python/qemu/README.rst                    |   8 +
>   python/Pipfile                            |  14 ++
>   python/Pipfile.lock                       | 195 ++++++++++++++++++++++
>   python/qemu/__init__.py                   |  11 --
>   python/qemu/{ => core}/.flake8            |   0
>   python/qemu/core/__init__.py              |  57 +++++++
>   python/qemu/{ => core}/accel.py           |   0
>   python/qemu/{ => core}/machine.py         |   0
>   python/qemu/{ => core}/pylintrc           |   0
>   python/qemu/{ => core}/qmp.py             |   0
>   python/qemu/{ => core}/qtest.py           |   0
>   python/setup.py                           |  50 ++++++
>   scripts/device-crash-test                 |   2 +-
>   scripts/qmp/qemu-ga-client                |   2 +-
>   scripts/qmp/qmp                           |   2 +-
>   scripts/qmp/qmp-shell                     |   2 +-
>   scripts/qmp/qom-fuse                      |   2 +-
>   scripts/qmp/qom-get                       |   2 +-
>   scripts/qmp/qom-list                      |   2 +-
>   scripts/qmp/qom-set                       |   2 +-
>   scripts/qmp/qom-tree                      |   2 +-
>   scripts/render_block_graph.py             |   6 +-
>   scripts/simplebench/bench_block_job.py    |   4 +-
>   tests/acceptance/avocado_qemu/__init__.py |   2 +-
>   tests/acceptance/boot_linux.py            |   3 +-
>   tests/acceptance/virtio_check_params.py   |   2 +-
>   tests/acceptance/virtio_version.py        |   2 +-
>   tests/migration/guestperf/engine.py       |   2 +-
>   tests/qemu-iotests/235                    |   2 +-
>   tests/qemu-iotests/297                    |   2 +-
>   tests/qemu-iotests/iotests.py             |   4 +-
>   tests/vm/basevm.py                        |   6 +-
>   33 files changed, 355 insertions(+), 39 deletions(-)
>   create mode 100644 python/README.rst
>   create mode 100644 python/qemu/README.rst
>   create mode 100644 python/Pipfile
>   create mode 100644 python/Pipfile.lock
>   delete mode 100644 python/qemu/__init__.py
>   rename python/qemu/{ => core}/.flake8 (100%)
>   create mode 100644 python/qemu/core/__init__.py
>   rename python/qemu/{ => core}/accel.py (100%)
>   rename python/qemu/{ => core}/machine.py (100%)
>   rename python/qemu/{ => core}/pylintrc (100%)
>   rename python/qemu/{ => core}/qmp.py (100%)
>   rename python/qemu/{ => core}/qtest.py (100%)
>   create mode 100755 python/setup.py
> 


-- 
Best regards,
Vladimir


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

* Re: [PATCH 0/7] python: create installable package
  2020-06-06  5:53 ` [PATCH 0/7] python: create installable package Vladimir Sementsov-Ogievskiy
@ 2020-06-08 14:14   ` John Snow
  0 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-08 14:14 UTC (permalink / raw)
  To: Vladimir Sementsov-Ogievskiy, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, Eduardo Habkost, qemu-block,
	Philippe Mathieu-Daudé,
	Markus Armbruster, Max Reitz, Stefan Hajnoczi, Cleber Rosa,
	Alex Bennée



On 6/6/20 1:53 AM, Vladimir Sementsov-Ogievskiy wrote:
> For patches 05-07:
> 
> Reviewing such patch is a strange thing: Pipfile changes are obvious
> enough, just select some version (I can't be sure about correct version
> choice, just believe in your commit messages). But what for
> Pipfile.lock? I can state that it's about package set selecting,
> Pipfile.lock looks like what it should be, but I have idea about all
> these packages, their versions and hashes (and even, does it correspond
> really to Pipfile or not) :)
> 
> Ha, what I can check, is: does pipenv create almost same Pipfile.lock in
> my environment (with 3.7.5 python)
> OK, I've tried (pipenv lock --dev --python /usr/bin/python3), and yes,
> result is almost the same. For mypy and importlib-metadata packages I
> have newer version and different hashes (of course). Other packages are
> the same. Set of packages is the same.
> 
> Hmm, but in may generated Pipfile.lock there no "markers". They are
> about python version and looks like "markers": "python_version >=
> '3.5'".. Does pipenv follow them? Then why they are not generated for
> me, did you use some additional command/option to create them?
> Anyway, they don't look dangerous, so for last three patches:
> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> 

Yes, from a blank repository you can do "pipenv install mypy>=0.730" --
it uses the same package specification syntax that pip uses.

(Or, you can edit the Pipfile manually, which is what I actually did.
The benefit of doing so is primarily about documenting our minimum
version requirements. I suppose in truth, those minimums should go into
setup.py too, actually.)

Thanks for taking a look!

--js

> 03.06.2020 03:15, John Snow wrote:
>> Based-on: 20200602214528.12107-1-jsnow@redhat.com
>>
>> This series factors the python/qemu directory as an installable
>> module. As a developer, you can install this to your virtual environment
>> and then always have access to the classes contained within without
>> needing to wrangle python import path problems.
>>
>> When developing, you could go to qemu/python/ and invoke `pipenv shell`
>> to activate a virtual environment within which you could type `pip
>> install -e .` to install a special development version of this package
>> to your virtual environment. This package will always reflect the most
>> recent version of the source files in the tree.
>>
>> When not developing, you could install a version of this package to your
>> environment outright to gain access to the QMP and QEMUMachine classes
>> for lightweight scripting and testing.
>>
>> This package is formatted in such a way that it COULD be uploaded to
>> https://pypi.org/project/qemu and installed independently of qemu.git
>> with `pip install qemu`, but of course that button remains unpushed.
>>
>> There are a few major questions to answer first:
>>
>> - What versioning scheme should we use? See patch 2.
>>
>> - Should we use a namespace package or not?
>>    - Namespaced: 'qemu.machine', 'qemu.monitor' etc may be separately
>>      versioned, packaged and distributed packages. Third party authors
>>      may register 'qemu.xxx' to create plugins within the namespace as
>>      they see fit.
>>
>>    - Non-namespaced: 'qemu' is one giant glob package, packaged and
>>      versioned in unison. We control this package exclusively.
>>
>> - How do we eliminate sys.path hacks from the rest of the QEMU tree?
>>    (Background: sys.path hacks generally impede the function of static
>>    code quality analysis tools like mypy and pylint.)
>>
>>    - Simplest: parent scripts (or developer) needs to set PYTHONPATH.
>>
>>    - Harder: Python scripts should all be written to assume package form,
>>      all tests and CI that use Python should execute within a VENV.
>>
>>    In either case, we lose the ability (for many scripts) to "just run" a
>>    script out of the source tree if it depends on other QEMU Python
>>    files. This is annoying, but as the complexity of the Python lib
>>    grows, it is unavoidable.
>>
>>    In the VENV case, we at least establish a simple paradigm: the scripts
>>    should work in their "installed" forms; and the rest of the build and
>>    test infrastructure should use this VENV to automatically handle
>>    dependencies and path requirements. This should allow us to move many
>>    of our existing python scripts with "hidden" dependencies into a
>>    proper python module hierarchy and test for regressions with mypy,
>>    flake8, pylint, etc.
>>
>>    (We could even establish e.g. Sphinx versions as a dependency for our
>>    build kit here and make sure it's installed to the VENV.)
>>
>>    Pros: Almost all scripts can be moved under python/qemu/* and checked
>>    with CQA tools. imports are written the same no matter where you are
>>    (Use the fully qualified names, e.g. qemu.core.qmp.QMPMessage).
>>    Regressions in scripts are caught *much* faster.
>>
>>    Downsides: Kind of annoying; most scripts now require you to install a
>>    devkit forwarder (pip3 install --user .) or be inside of an activated
>>    venv. Not too bad if you know python at all, but it's certainly less
>>    plug-n-play.
>>
>> - What's our backwards compatibility policy if we start shipping this?
>>
>>    Proposed: Attempt to maintain API compatibility (after stabilizing the
>>    library). Incompatible changes should probably cause a semver bump.
>>
>>    Each published release makes no attempt to support any version of QEMU
>>    other than the one it was released against. We publish this on the tin
>>    in big red letters.
>>
>> TESTING THIS PACKAGE OUT:
>>
>> 1. You can install to your local user's environment normally by
>> navigating to qemu/python/ and typing "pip3 install --user ."
>>
>> 2. If you are in a VENV, use "pip install ."
>>
>> 3. To install in development mode (Where the installed package always
>> reflects the most recent version of the files automatically), use "pip3
>> install -e ." or "pip install -e ." as appropriate (See above)
>>
>> John Snow (7):
>>    python/qemu: create qemu.lib module
>>    python/qemu: formalize as package
>>    python/qemu: add README.rst
>>    python/qemu: Add pipenv support
>>    python/qemu: add pylint to pipenv
>>    python/qemu: Add flake8 to pipenv
>>    python/qemu: add mypy to pipenv
>>
>>   python/README.rst                         |   6 +
>>   python/qemu/README.rst                    |   8 +
>>   python/Pipfile                            |  14 ++
>>   python/Pipfile.lock                       | 195 ++++++++++++++++++++++
>>   python/qemu/__init__.py                   |  11 --
>>   python/qemu/{ => core}/.flake8            |   0
>>   python/qemu/core/__init__.py              |  57 +++++++
>>   python/qemu/{ => core}/accel.py           |   0
>>   python/qemu/{ => core}/machine.py         |   0
>>   python/qemu/{ => core}/pylintrc           |   0
>>   python/qemu/{ => core}/qmp.py             |   0
>>   python/qemu/{ => core}/qtest.py           |   0
>>   python/setup.py                           |  50 ++++++
>>   scripts/device-crash-test                 |   2 +-
>>   scripts/qmp/qemu-ga-client                |   2 +-
>>   scripts/qmp/qmp                           |   2 +-
>>   scripts/qmp/qmp-shell                     |   2 +-
>>   scripts/qmp/qom-fuse                      |   2 +-
>>   scripts/qmp/qom-get                       |   2 +-
>>   scripts/qmp/qom-list                      |   2 +-
>>   scripts/qmp/qom-set                       |   2 +-
>>   scripts/qmp/qom-tree                      |   2 +-
>>   scripts/render_block_graph.py             |   6 +-
>>   scripts/simplebench/bench_block_job.py    |   4 +-
>>   tests/acceptance/avocado_qemu/__init__.py |   2 +-
>>   tests/acceptance/boot_linux.py            |   3 +-
>>   tests/acceptance/virtio_check_params.py   |   2 +-
>>   tests/acceptance/virtio_version.py        |   2 +-
>>   tests/migration/guestperf/engine.py       |   2 +-
>>   tests/qemu-iotests/235                    |   2 +-
>>   tests/qemu-iotests/297                    |   2 +-
>>   tests/qemu-iotests/iotests.py             |   4 +-
>>   tests/vm/basevm.py                        |   6 +-
>>   33 files changed, 355 insertions(+), 39 deletions(-)
>>   create mode 100644 python/README.rst
>>   create mode 100644 python/qemu/README.rst
>>   create mode 100644 python/Pipfile
>>   create mode 100644 python/Pipfile.lock
>>   delete mode 100644 python/qemu/__init__.py
>>   rename python/qemu/{ => core}/.flake8 (100%)
>>   create mode 100644 python/qemu/core/__init__.py
>>   rename python/qemu/{ => core}/accel.py (100%)
>>   rename python/qemu/{ => core}/machine.py (100%)
>>   rename python/qemu/{ => core}/pylintrc (100%)
>>   rename python/qemu/{ => core}/qmp.py (100%)
>>   rename python/qemu/{ => core}/qtest.py (100%)
>>   create mode 100755 python/setup.py
>>
> 
> 

-- 
—js



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

* Re: [PATCH 0/7] python: create installable package
  2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
                   ` (7 preceding siblings ...)
  2020-06-06  5:53 ` [PATCH 0/7] python: create installable package Vladimir Sementsov-Ogievskiy
@ 2020-06-17 19:52 ` Cleber Rosa
  2020-06-17 20:27   ` John Snow
  8 siblings, 1 reply; 30+ messages in thread
From: Cleber Rosa @ 2020-06-17 19:52 UTC (permalink / raw)
  To: John Snow
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Stefan Hajnoczi, Max Reitz,
	Alex Bennée

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

On Tue, Jun 02, 2020 at 08:15:16PM -0400, John Snow wrote:
> Based-on: 20200602214528.12107-1-jsnow@redhat.com
> 
> This series factors the python/qemu directory as an installable
> module. As a developer, you can install this to your virtual environment
> and then always have access to the classes contained within without
> needing to wrangle python import path problems.
>

First of all, major kudos for picking up this task.  It's so high in
importance to so many users (myself included) that I feel like I owe
you many truck loads of beers now. :)

> When developing, you could go to qemu/python/ and invoke `pipenv shell`
> to activate a virtual environment within which you could type `pip
> install -e .` to install a special development version of this package
> to your virtual environment. This package will always reflect the most
> recent version of the source files in the tree.
> 
> When not developing, you could install a version of this package to your
> environment outright to gain access to the QMP and QEMUMachine classes
> for lightweight scripting and testing.
> 
> This package is formatted in such a way that it COULD be uploaded to
> https://pypi.org/project/qemu and installed independently of qemu.git
> with `pip install qemu`, but of course that button remains unpushed.
> 
> There are a few major questions to answer first:
> 
> - What versioning scheme should we use? See patch 2.
> 
> - Should we use a namespace package or not?
>   - Namespaced: 'qemu.machine', 'qemu.monitor' etc may be separately
>     versioned, packaged and distributed packages. Third party authors
>     may register 'qemu.xxx' to create plugins within the namespace as
>     they see fit.
> 
>   - Non-namespaced: 'qemu' is one giant glob package, packaged and
>     versioned in unison. We control this package exclusively.
>

For simplicity sake, I'd suggest starting with non-namespaced
approach.  It should be easier to move to a namespaced package if the
need arises.  Also, there are many ways to extend Python code without
necessarily requiring third party authors to register their packages
according to a namespace.

In the Avocado project, we have been using setuptools entrypoints with
a reasonable level of success.  Anyone can have code under any
namespace whatsoever extending Avocado, as long as it register their
entrypoints.

> - How do we eliminate sys.path hacks from the rest of the QEMU tree?
>   (Background: sys.path hacks generally impede the function of static
>   code quality analysis tools like mypy and pylint.)
> 
>   - Simplest: parent scripts (or developer) needs to set PYTHONPATH.
> 
>   - Harder: Python scripts should all be written to assume package form,
>     all tests and CI that use Python should execute within a VENV.
>

Having a venv is desirable, but it's not really necessary.  As long as
"python setup.py develop --user" is called, that user can access this
code without sys.path hacks.  And if the user chooses to use a venv,
it's just an extra step.

In the Avocado project, we have a `make develop` rule that does that
for the main setup.py file, and for all plugins we carry on the same
tree, which is similar in some regards to the "not at the project root
directory" situation here with "qemu/python/setup.py".

>   In either case, we lose the ability (for many scripts) to "just run" a
>   script out of the source tree if it depends on other QEMU Python
>   files. This is annoying, but as the complexity of the Python lib
>   grows, it is unavoidable.
>

Like I said before, we may introduce a "make develop"-like
requirement, but after that, I don't think we'll loose anything.
Also, I think this is just a sign of maturity.  We should be using
Python as it's inteded to be used, and sys.path hacks is not among
those.

>   In the VENV case, we at least establish a simple paradigm: the scripts
>   should work in their "installed" forms; and the rest of the build and
>   test infrastructure should use this VENV to automatically handle
>   dependencies and path requirements. This should allow us to move many
>   of our existing python scripts with "hidden" dependencies into a
>   proper python module hierarchy and test for regressions with mypy,
>   flake8, pylint, etc.
> 
>   (We could even establish e.g. Sphinx versions as a dependency for our
>   build kit here and make sure it's installed to the VENV.)
> 
>   Pros: Almost all scripts can be moved under python/qemu/* and checked
>   with CQA tools. imports are written the same no matter where you are
>   (Use the fully qualified names, e.g. qemu.core.qmp.QMPMessage).
>   Regressions in scripts are caught *much* faster.
> 
>   Downsides: Kind of annoying; most scripts now require you to install a
>   devkit forwarder (pip3 install --user .) or be inside of an activated
>   venv. Not too bad if you know python at all, but it's certainly less
>   plug-n-play.
> 
> - What's our backwards compatibility policy if we start shipping this?
> 
>   Proposed: Attempt to maintain API compatibility (after stabilizing the
>   library). Incompatible changes should probably cause a semver bump.
>
>   Each published release makes no attempt to support any version of QEMU
>   other than the one it was released against. We publish this on the tin
>   in big red letters.

It may be too early to tell, but it's not clear to me how we'll keep
both the QEMU version supported by a given release, and its API
"level".

Are you proposing that we have, say, "python-qemu" version 10, being
the 10th API version, without any regard to the QEMU version
supported?  Or version 10.5.3 would mean 10th API version, intended
to support QEMU 5.3?

> 
> TESTING THIS PACKAGE OUT:
> 
> 1. You can install to your local user's environment normally by
> navigating to qemu/python/ and typing "pip3 install --user ."
>

s/install/develop/ should be a better option here.  I mean, I'm
not aware of any reason to user install while developing.

- Cleber.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 0/7] python: create installable package
  2020-06-17 19:52 ` Cleber Rosa
@ 2020-06-17 20:27   ` John Snow
  2020-06-18  9:23     ` Kevin Wolf
  2020-06-19 15:15     ` Philippe Mathieu-Daudé
  0 siblings, 2 replies; 30+ messages in thread
From: John Snow @ 2020-06-17 20:27 UTC (permalink / raw)
  To: Cleber Rosa
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Stefan Hajnoczi, Max Reitz,
	Alex Bennée



On 6/17/20 3:52 PM, Cleber Rosa wrote:
> On Tue, Jun 02, 2020 at 08:15:16PM -0400, John Snow wrote:
>> Based-on: 20200602214528.12107-1-jsnow@redhat.com
>>
>> This series factors the python/qemu directory as an installable
>> module. As a developer, you can install this to your virtual environment
>> and then always have access to the classes contained within without
>> needing to wrangle python import path problems.
>>
> 
> First of all, major kudos for picking up this task.  It's so high in
> importance to so many users (myself included) that I feel like I owe
> you many truck loads of beers now. :)
> 

Mostly I just wanted to formalize mypy, pylint, flake8 et al across the
most important python bits in our tree so that when making changes for
testing it's easier to verify that I didn't break something else.

Easiest way to get the right structure that these tools expect is to
make a real package ...

So here we are. And also Philippe asked nicely.

>> When developing, you could go to qemu/python/ and invoke `pipenv shell`
>> to activate a virtual environment within which you could type `pip
>> install -e .` to install a special development version of this package
>> to your virtual environment. This package will always reflect the most
>> recent version of the source files in the tree.
>>
>> When not developing, you could install a version of this package to your
>> environment outright to gain access to the QMP and QEMUMachine classes
>> for lightweight scripting and testing.
>>
>> This package is formatted in such a way that it COULD be uploaded to
>> https://pypi.org/project/qemu and installed independently of qemu.git
>> with `pip install qemu`, but of course that button remains unpushed.
>>
>> There are a few major questions to answer first:
>>
>> - What versioning scheme should we use? See patch 2.
>>
>> - Should we use a namespace package or not?
>>   - Namespaced: 'qemu.machine', 'qemu.monitor' etc may be separately
>>     versioned, packaged and distributed packages. Third party authors
>>     may register 'qemu.xxx' to create plugins within the namespace as
>>     they see fit.
>>
>>   - Non-namespaced: 'qemu' is one giant glob package, packaged and
>>     versioned in unison. We control this package exclusively.
>>
> 
> For simplicity sake, I'd suggest starting with non-namespaced
> approach.  It should be easier to move to a namespaced package if the
> need arises.  Also, there are many ways to extend Python code without
> necessarily requiring third party authors to register their packages
> according to a namespace.
> 
> In the Avocado project, we have been using setuptools entrypoints with
> a reasonable level of success.  Anyone can have code under any
> namespace whatsoever extending Avocado, as long as it register their
> entrypoints.
> 

It's not (from my POV) very complex to do a namespace. I have some plans
to move e.g. qapi into qemu.qapi, and some of our other tools into
qemu.tools.

Some of these packages can be published externally, some can remain in
the tree.

but -- maybe namespaces ARE complicating matters in ways I don't
understand yet. I'll be open about it. The thought was mostly about
keeping flexibility with just installing the bits and pieces that you
want/need.

>> - How do we eliminate sys.path hacks from the rest of the QEMU tree?
>>   (Background: sys.path hacks generally impede the function of static
>>   code quality analysis tools like mypy and pylint.)
>>
>>   - Simplest: parent scripts (or developer) needs to set PYTHONPATH.
>>
>>   - Harder: Python scripts should all be written to assume package form,
>>     all tests and CI that use Python should execute within a VENV.
>>
> 
> Having a venv is desirable, but it's not really necessary.  As long as
> "python setup.py develop --user" is called, that user can access this
> code without sys.path hacks.  And if the user chooses to use a venv,
> it's just an extra step.
> 

whether a venv or a user installation, it's the same thing, really: the
user needs to set up and be in that environment to use the python tools
in the tree.

Once we're there, we may as well formalize the VENV to make it easier to
set up and use.

> In the Avocado project, we have a `make develop` rule that does that
> for the main setup.py file, and for all plugins we carry on the same
> tree, which is similar in some regards to the "not at the project root
> directory" situation here with "qemu/python/setup.py".
> 

Ah, yeah. If we're going this far, I'd prefer using a VENV over
modifying the user's environment. That way you can blast it all away
with a `make distclean`.

Maybe the "make develop" target could even use the presence of a .venv
directory to know when it needs to make the environment or not ...

>>   In either case, we lose the ability (for many scripts) to "just run" a
>>   script out of the source tree if it depends on other QEMU Python
>>   files. This is annoying, but as the complexity of the Python lib
>>   grows, it is unavoidable.
>>
> 
> Like I said before, we may introduce a "make develop"-like
> requirement, but after that, I don't think we'll loose anything.
> Also, I think this is just a sign of maturity.  We should be using
> Python as it's inteded to be used, and sys.path hacks is not among
> those.
> 

Joking nitpick: There is no intended way to use Python! :)

Still, the sys.path hacks -- worse than being "unpythonic", actively
seem to get in the way of pylint, flake8, mypy et al which do provide us
with legitimate and serious value.

So, sad to say, but we might lose the ability to run these python
scripts ad-hoc out of the tree (with no setup) in order to gain a more
robust python CI regime.

I think it's a fair trade-off, but we'll see if that's born out in review.

>>   In the VENV case, we at least establish a simple paradigm: the scripts
>>   should work in their "installed" forms; and the rest of the build and
>>   test infrastructure should use this VENV to automatically handle
>>   dependencies and path requirements. This should allow us to move many
>>   of our existing python scripts with "hidden" dependencies into a
>>   proper python module hierarchy and test for regressions with mypy,
>>   flake8, pylint, etc.
>>
>>   (We could even establish e.g. Sphinx versions as a dependency for our
>>   build kit here and make sure it's installed to the VENV.)
>>
>>   Pros: Almost all scripts can be moved under python/qemu/* and checked
>>   with CQA tools. imports are written the same no matter where you are
>>   (Use the fully qualified names, e.g. qemu.core.qmp.QMPMessage).
>>   Regressions in scripts are caught *much* faster.
>>
>>   Downsides: Kind of annoying; most scripts now require you to install a
>>   devkit forwarder (pip3 install --user .) or be inside of an activated
>>   venv. Not too bad if you know python at all, but it's certainly less
>>   plug-n-play.
>>
>> - What's our backwards compatibility policy if we start shipping this?
>>
>>   Proposed: Attempt to maintain API compatibility (after stabilizing the
>>   library). Incompatible changes should probably cause a semver bump.
>>
>>   Each published release makes no attempt to support any version of QEMU
>>   other than the one it was released against. We publish this on the tin
>>   in big red letters.
> 
> It may be too early to tell, but it's not clear to me how we'll keep
> both the QEMU version supported by a given release, and its API
> "level".
> 
> Are you proposing that we have, say, "python-qemu" version 10, being
> the 10th API version, without any regard to the QEMU version
> supported?  Or version 10.5.3 would mean 10th API version, intended
> to support QEMU 5.3?
> 

I am proposing only that we use semver to track the API version of the
SDK itself.

So that could be:

A) 1.x, 2.x, 3.x (etc) with absolutely no connection to the intended
QEMU support version. It either works or it doesn't. It might not work
very spectacularly. Major semver bumps indicate a breaking change to the
library API.

B) 1.5.0.0, 1.5.1.0, 1.5.2.0 (etc) where the major version still
describes the API, but the remainder of the version describes the
intended target QEMU.

Or, we could do:

C) 5.0.0, 5.1.0, 5.2.0, etc. where it tracks the QEMU version verbatim,
end of story.


I don't like (C) very much, because it violates some prevailing idioms
about python package versioning. A or B seem better, but do run us into
potential trouble with people having mismatched versions.

I'd take A or B. (B) is a little chatty but gives some good information
and allows you to pin versions effectively, so I think I'm leaning
towards that one right now.

Well, whatever we do right now, I think I do really want to make sure we
are publishing under 0.x to really give the illustration that we are NOT
promising even the illusion of stability right now.

>>
>> TESTING THIS PACKAGE OUT:
>>
>> 1. You can install to your local user's environment normally by
>> navigating to qemu/python/ and typing "pip3 install --user ."
>>
> 
> s/install/develop/ should be a better option here.  I mean, I'm
> not aware of any reason to user install while developing.
> 

I tried to make note to the develop case in several places; for the
purposes of this email I wanted to demonstrate what installing and using
it as a user would look like.

For those unaware of the distinction:

- install does a real bona-fide installation.
- develop installs a forwarder package that references the living
development files, so the package contents (but NOT its metadata!) are
always up to date with your development files.

For QEMU developers, installing with develop is going to be the smart
way to go. When your git tree is updated, your package will be updated
along with it. You can do it once and then probably forget about it.

> - Cleber.
> 




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

* Re: [PATCH 0/7] python: create installable package
  2020-06-17 20:27   ` John Snow
@ 2020-06-18  9:23     ` Kevin Wolf
  2020-06-19 15:04       ` John Snow
  2020-06-19 15:09       ` Philippe Mathieu-Daudé
  2020-06-19 15:15     ` Philippe Mathieu-Daudé
  1 sibling, 2 replies; 30+ messages in thread
From: Kevin Wolf @ 2020-06-18  9:23 UTC (permalink / raw)
  To: John Snow
  Cc: Fam Zheng, Vladimir Sementsov-Ogievskiy, Eduardo Habkost,
	qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Stefan Hajnoczi, Cleber Rosa,
	Max Reitz, Alex Bennée

Am 17.06.2020 um 22:27 hat John Snow geschrieben:
> > In the Avocado project, we have a `make develop` rule that does that
> > for the main setup.py file, and for all plugins we carry on the same
> > tree, which is similar in some regards to the "not at the project root
> > directory" situation here with "qemu/python/setup.py".
> > 
> 
> Ah, yeah. If we're going this far, I'd prefer using a VENV over
> modifying the user's environment. That way you can blast it all away
> with a `make distclean`.
> 
> Maybe the "make develop" target could even use the presence of a .venv
> directory to know when it needs to make the environment or not ...
[..]
> For QEMU developers, installing with develop is going to be the smart
> way to go. When your git tree is updated, your package will be updated
> along with it. You can do it once and then probably forget about it.

I don't think we can make this a manual step at all. Building QEMU
requires running some Python scripts (e.g. the QAPI generator), so the
setup needs to be done either in configure or in a Makefile target that
is specified as a dependency of any rule that would run a Python script.
Building QEMU once would then be enough.

Doing it automatically also means that we have to keep things local to
the QEMU directory rather than installing them globally into the user
directory. This is desirable anyway: Most of us deal with more than one
QEMU source tree, so conflicts would be inevitable.

Kevin



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

* Re: [PATCH 0/7] python: create installable package
  2020-06-18  9:23     ` Kevin Wolf
@ 2020-06-19 15:04       ` John Snow
  2020-06-19 16:44         ` Kevin Wolf
  2020-06-19 15:09       ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 30+ messages in thread
From: John Snow @ 2020-06-19 15:04 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Fam Zheng, Vladimir Sementsov-Ogievskiy, Eduardo Habkost,
	qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Stefan Hajnoczi, Cleber Rosa,
	Max Reitz, Alex Bennée



On 6/18/20 5:23 AM, Kevin Wolf wrote:
> Am 17.06.2020 um 22:27 hat John Snow geschrieben:
>>> In the Avocado project, we have a `make develop` rule that does that
>>> for the main setup.py file, and for all plugins we carry on the same
>>> tree, which is similar in some regards to the "not at the project root
>>> directory" situation here with "qemu/python/setup.py".
>>>
>>
>> Ah, yeah. If we're going this far, I'd prefer using a VENV over
>> modifying the user's environment. That way you can blast it all away
>> with a `make distclean`.
>>
>> Maybe the "make develop" target could even use the presence of a .venv
>> directory to know when it needs to make the environment or not ...
> [..]
>> For QEMU developers, installing with develop is going to be the smart
>> way to go. When your git tree is updated, your package will be updated
>> along with it. You can do it once and then probably forget about it.
> 
> I don't think we can make this a manual step at all. Building QEMU
> requires running some Python scripts (e.g. the QAPI generator), so the
> setup needs to be done either in configure or in a Makefile target that
> is specified as a dependency of any rule that would run a Python script.
> Building QEMU once would then be enough.
> 

I am imagining that we might treat "building" and "testing" separately
-- as it is, builds require python3.5 and tests requires 3.6 which
definitely necessitates two distinct environments.

I will admit that I haven't constructed a full, coherent vision of
python management that encapsulates both building ad testing yet. For
example, should configure/make expect to be run inside of a venv, or
should they expect to create and then enter the venv? That's not clear
to me yet. I'm simultaneously trying to work out with Peter Maydell how
the sphinx dependency should work. Sphinx is presently our only python
dependency for our build environment.)

Perhaps starting with the testing step is a good starting point and we
can use an implicit dependency on a `make develop` style step so it
happens automatically.

(But perhaps keeping it as a standalone target that CAN be invoked
manually would be nice if you want to do some more intensive debugging
or development of new tests.)

> Doing it automatically also means that we have to keep things local to
> the QEMU directory rather than installing them globally into the user
> directory. This is desirable anyway: Most of us deal with more than one
> QEMU source tree, so conflicts would be inevitable.
> 

I think it should be easy enough to put the VENV in the build directory
to prevent cross-contamination.

> Kevin
> 



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

* Re: [PATCH 0/7] python: create installable package
  2020-06-18  9:23     ` Kevin Wolf
  2020-06-19 15:04       ` John Snow
@ 2020-06-19 15:09       ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-06-19 15:09 UTC (permalink / raw)
  To: Kevin Wolf, John Snow
  Cc: Fam Zheng, Vladimir Sementsov-Ogievskiy, Eduardo Habkost,
	qemu-block, Markus Armbruster, qemu-devel, Stefan Hajnoczi,
	Cleber Rosa, Max Reitz, Alex Bennée

On 6/18/20 11:23 AM, Kevin Wolf wrote:
> Am 17.06.2020 um 22:27 hat John Snow geschrieben:
>>> In the Avocado project, we have a `make develop` rule that does that
>>> for the main setup.py file, and for all plugins we carry on the same
>>> tree, which is similar in some regards to the "not at the project root
>>> directory" situation here with "qemu/python/setup.py".
>>>
>>
>> Ah, yeah. If we're going this far, I'd prefer using a VENV over
>> modifying the user's environment. That way you can blast it all away
>> with a `make distclean`.
>>
>> Maybe the "make develop" target could even use the presence of a .venv
>> directory to know when it needs to make the environment or not ...
> [..]
>> For QEMU developers, installing with develop is going to be the smart
>> way to go. When your git tree is updated, your package will be updated
>> along with it. You can do it once and then probably forget about it.
> 
> I don't think we can make this a manual step at all. Building QEMU
> requires running some Python scripts (e.g. the QAPI generator), so the
> setup needs to be done either in configure or in a Makefile target that
> is specified as a dependency of any rule that would run a Python script.
> Building QEMU once would then be enough.
> 
> Doing it automatically also means that we have to keep things local to
> the QEMU directory rather than installing them globally into the user
> directory. This is desirable anyway: Most of us deal with more than one
> QEMU source tree, so conflicts would be inevitable.

Indeed. Each of the source tree I use has its own virtual environment.
I personally stopped using the distribution packages, they don't make
sense when you develop, the tree changes too quickly.

Distributions use stable releases, so IMO it only makes sense to
generate a package along with releases. Else use venv.



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

* Re: [PATCH 0/7] python: create installable package
  2020-06-17 20:27   ` John Snow
  2020-06-18  9:23     ` Kevin Wolf
@ 2020-06-19 15:15     ` Philippe Mathieu-Daudé
  2020-06-19 16:10       ` John Snow
  1 sibling, 1 reply; 30+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-06-19 15:15 UTC (permalink / raw)
  To: John Snow, Cleber Rosa
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, qemu-devel, Markus Armbruster,
	Stefan Hajnoczi, Max Reitz, Alex Bennée

On 6/17/20 10:27 PM, John Snow wrote:
> 
> 
> On 6/17/20 3:52 PM, Cleber Rosa wrote:
>> On Tue, Jun 02, 2020 at 08:15:16PM -0400, John Snow wrote:
[...]
>> Are you proposing that we have, say, "python-qemu" version 10, being
>> the 10th API version, without any regard to the QEMU version
>> supported?  Or version 10.5.3 would mean 10th API version, intended
>> to support QEMU 5.3?
>>
> 
> I am proposing only that we use semver to track the API version of the
> SDK itself.
> 
> So that could be:
> 
> A) 1.x, 2.x, 3.x (etc) with absolutely no connection to the intended
> QEMU support version. It either works or it doesn't. It might not work
> very spectacularly. Major semver bumps indicate a breaking change to the
> library API.

Major changes occurs between QEMU releases. If there is no QEMU release,
it is pointless to release the python-qemu package, right?

> 
> B) 1.5.0.0, 1.5.1.0, 1.5.2.0 (etc) where the major version still
> describes the API, but the remainder of the version describes the
> intended target QEMU.
> 
> Or, we could do:
> 
> C) 5.0.0, 5.1.0, 5.2.0, etc. where it tracks the QEMU version verbatim,
> end of story.

At least it KISS.

> 
> I don't like (C) very much, because it violates some prevailing idioms
> about python package versioning. A or B seem better, but do run us into
> potential trouble with people having mismatched versions.

Which is why I prefer (C).

> 
> I'd take A or B. (B) is a little chatty but gives some good information
> and allows you to pin versions effectively, so I think I'm leaning
> towards that one right now.
> 
> Well, whatever we do right now, I think I do really want to make sure we
> are publishing under 0.x to really give the illustration that we are NOT
> promising even the illusion of stability right now.



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

* Re: [PATCH 0/7] python: create installable package
  2020-06-19 15:15     ` Philippe Mathieu-Daudé
@ 2020-06-19 16:10       ` John Snow
  0 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-19 16:10 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, Cleber Rosa
  Cc: Kevin Wolf, Fam Zheng, Vladimir Sementsov-Ogievskiy,
	Eduardo Habkost, qemu-block, qemu-devel,
	Wainer dos Santos Moschetta, Markus Armbruster, Stefan Hajnoczi,
	Cleber Rosa, Max Reitz, Alex Bennée



On 6/19/20 11:15 AM, Philippe Mathieu-Daudé wrote:
> On 6/17/20 10:27 PM, John Snow wrote:
>>
>>
>> On 6/17/20 3:52 PM, Cleber Rosa wrote:
>>> On Tue, Jun 02, 2020 at 08:15:16PM -0400, John Snow wrote:
> [...]
>>> Are you proposing that we have, say, "python-qemu" version 10, being
>>> the 10th API version, without any regard to the QEMU version
>>> supported?  Or version 10.5.3 would mean 10th API version, intended
>>> to support QEMU 5.3?
>>>
>>
>> I am proposing only that we use semver to track the API version of the
>> SDK itself.
>>
>> So that could be:
>>
>> A) 1.x, 2.x, 3.x (etc) with absolutely no connection to the intended
>> QEMU support version. It either works or it doesn't. It might not work
>> very spectacularly. Major semver bumps indicate a breaking change to the
>> library API.
> 
> Major changes occurs between QEMU releases. If there is no QEMU release,
> it is pointless to release the python-qemu package, right?
> 

There might be fixes to the package that might be worth releasing
out-of-band as point fixes. I don't intend to do this if I can help it,
but I wanted to consider the possibility that unforeseen circumstances
might force our hand.

>>
>> B) 1.5.0.0, 1.5.1.0, 1.5.2.0 (etc) where the major version still
>> describes the API, but the remainder of the version describes the
>> intended target QEMU.
>>
>> Or, we could do:
>>
>> C) 5.0.0, 5.1.0, 5.2.0, etc. where it tracks the QEMU version verbatim,
>> end of story.
> 
> At least it KISS.
> 

Simple at a glance.

I have some concerns about how Python packages are normally specified in
e.g. requirements.txt where there's a habit of saying:

package>=3.0.0, <4.0.0

There is a fairly common belief in the ecosystem that semver is being
used. QEMU does not use semver.

This leads us to a strange development paradigm in-tree where the Python
package can have breaking changes from 5.x to 6.x, which are not
otherwise special releases for QEMU itself.

Combined with our deprecation policy, it means that we start adopting a
policy like:

- Features get deprecated for at least two releases
- But can only be changed for a new "major" release.

That mismatch against the QEMU versioning paradigm does not sound like
KISS to me.

>>
>> I don't like (C) very much, because it violates some prevailing idioms
>> about python package versioning. A or B seem better, but do run us into
>> potential trouble with people having mismatched versions.
> 
> Which is why I prefer (C).
> 

Keep in mind that even though it looks more obvious, it still doesn't
enforce the pairing. Problems with mismatched versions are just as
likely to occur because of misconfigurations with requirements.txt.

I guess my big concerns here are:

1. Using 1:1 QEMU versions (starting at 5.x) might imply API stability
for the package, and I would like to avoid committing to that. We *can*
declare the package as Alpha/Beta in PyPI, but in practice I am not sure
that information is consulted as readily as version numbers are.

2. Python world (Citation Needed?) expects semver. We can ignore that if
we choose; there aren't semver police. What are the consequences of
doing that?

3. No matter what we do, the relationship between the Python package and
the QEMU version is only superficial and isn't enforced anywhere. (And,
I think, shouldn't be enforced.)

>>
>> I'd take A or B. (B) is a little chatty but gives some good information
>> and allows you to pin versions effectively, so I think I'm leaning
>> towards that one right now.
>>
>> Well, whatever we do right now, I think I do really want to make sure we
>> are publishing under 0.x to really give the illustration that we are NOT
>> promising even the illusion of stability right now.
> 

It sounds like Avocado might be one of the biggest users of this, so I'd
like to get some more feedback from Cleber, Wainer, et al.

--js



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

* Re: [PATCH 0/7] python: create installable package
  2020-06-19 15:04       ` John Snow
@ 2020-06-19 16:44         ` Kevin Wolf
  2020-06-19 17:14           ` John Snow
  0 siblings, 1 reply; 30+ messages in thread
From: Kevin Wolf @ 2020-06-19 16:44 UTC (permalink / raw)
  To: John Snow
  Cc: Fam Zheng, Vladimir Sementsov-Ogievskiy, Eduardo Habkost,
	qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Stefan Hajnoczi, Cleber Rosa,
	Max Reitz, Alex Bennée

Am 19.06.2020 um 17:04 hat John Snow geschrieben:
> On 6/18/20 5:23 AM, Kevin Wolf wrote:
> > Am 17.06.2020 um 22:27 hat John Snow geschrieben:
> >>> In the Avocado project, we have a `make develop` rule that does that
> >>> for the main setup.py file, and for all plugins we carry on the same
> >>> tree, which is similar in some regards to the "not at the project root
> >>> directory" situation here with "qemu/python/setup.py".
> >>>
> >>
> >> Ah, yeah. If we're going this far, I'd prefer using a VENV over
> >> modifying the user's environment. That way you can blast it all away
> >> with a `make distclean`.
> >>
> >> Maybe the "make develop" target could even use the presence of a .venv
> >> directory to know when it needs to make the environment or not ...
> > [..]
> >> For QEMU developers, installing with develop is going to be the smart
> >> way to go. When your git tree is updated, your package will be updated
> >> along with it. You can do it once and then probably forget about it.
> > 
> > I don't think we can make this a manual step at all. Building QEMU
> > requires running some Python scripts (e.g. the QAPI generator), so the
> > setup needs to be done either in configure or in a Makefile target that
> > is specified as a dependency of any rule that would run a Python script.
> > Building QEMU once would then be enough.
> 
> I am imagining that we might treat "building" and "testing" separately
> -- as it is, builds require python3.5 and tests requires 3.6 which
> definitely necessitates two distinct environments.

I'm not sure what the exact definition of "end of life" of a distro is
that we're using. I seem to remember that the reason for using Python
3.5 was Debian Stretch. Its official end of life is in about three
weeks, but then there is still some LTS thing with reduced support done
by a different group.

If we read our policy literally and use the regular end of life, I guess
we could just move QEMU to 3.6 for everything.

> I will admit that I haven't constructed a full, coherent vision of
> python management that encapsulates both building ad testing yet. For
> example, should configure/make expect to be run inside of a venv, or
> should they expect to create and then enter the venv? That's not clear
> to me yet. I'm simultaneously trying to work out with Peter Maydell how
> the sphinx dependency should work. Sphinx is presently our only python
> dependency for our build environment.)

It's kind of obvious that this can't require user interaction because we
want ./configure; make to work. So I guess this means the venv needs to
be set up automatically by configure/make?

> Perhaps starting with the testing step is a good starting point and we
> can use an implicit dependency on a `make develop` style step so it
> happens automatically.
> 
> (But perhaps keeping it as a standalone target that CAN be invoked
> manually would be nice if you want to do some more intensive debugging
> or development of new tests.)

Yes. And you'll have many dependencies on it, so it would be a separate
target anyway.

> > Doing it automatically also means that we have to keep things local to
> > the QEMU directory rather than installing them globally into the user
> > directory. This is desirable anyway: Most of us deal with more than one
> > QEMU source tree, so conflicts would be inevitable.
> 
> I think it should be easy enough to put the VENV in the build directory
> to prevent cross-contamination.

Sure. I'm not overly familiar with all of this, but I guess my point was
just that a venv is needed rather than a global installation into the
user directory. If nobody ever suggested the latter, blame the
misunderstanding on my non-existent experience with more complex Python
setups.

Kevin



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

* Re: [PATCH 0/7] python: create installable package
  2020-06-19 16:44         ` Kevin Wolf
@ 2020-06-19 17:14           ` John Snow
  0 siblings, 0 replies; 30+ messages in thread
From: John Snow @ 2020-06-19 17:14 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Fam Zheng, Vladimir Sementsov-Ogievskiy, Eduardo Habkost,
	qemu-block, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Stefan Hajnoczi, Cleber Rosa,
	Max Reitz, Alex Bennée



On 6/19/20 12:44 PM, Kevin Wolf wrote:
> Am 19.06.2020 um 17:04 hat John Snow geschrieben:
>> On 6/18/20 5:23 AM, Kevin Wolf wrote:
>>> Am 17.06.2020 um 22:27 hat John Snow geschrieben:
>>>>> In the Avocado project, we have a `make develop` rule that does that
>>>>> for the main setup.py file, and for all plugins we carry on the same
>>>>> tree, which is similar in some regards to the "not at the project root
>>>>> directory" situation here with "qemu/python/setup.py".
>>>>>
>>>>
>>>> Ah, yeah. If we're going this far, I'd prefer using a VENV over
>>>> modifying the user's environment. That way you can blast it all away
>>>> with a `make distclean`.
>>>>
>>>> Maybe the "make develop" target could even use the presence of a .venv
>>>> directory to know when it needs to make the environment or not ...
>>> [..]
>>>> For QEMU developers, installing with develop is going to be the smart
>>>> way to go. When your git tree is updated, your package will be updated
>>>> along with it. You can do it once and then probably forget about it.
>>>
>>> I don't think we can make this a manual step at all. Building QEMU
>>> requires running some Python scripts (e.g. the QAPI generator), so the
>>> setup needs to be done either in configure or in a Makefile target that
>>> is specified as a dependency of any rule that would run a Python script.
>>> Building QEMU once would then be enough.
>>
>> I am imagining that we might treat "building" and "testing" separately
>> -- as it is, builds require python3.5 and tests requires 3.6 which
>> definitely necessitates two distinct environments.
> 
> I'm not sure what the exact definition of "end of life" of a distro is
> that we're using. I seem to remember that the reason for using Python
> 3.5 was Debian Stretch. Its official end of life is in about three
> weeks, but then there is still some LTS thing with reduced support done
> by a different group.
> 
> If we read our policy literally and use the regular end of life, I guess
> we could just move QEMU to 3.6 for everything.
> 

I think we have kinda-sorta-agreed to exclude the third-party LTS
support. I think we will be able to move to Python 3.6 shortly.

That'd solve one problem.

>> I will admit that I haven't constructed a full, coherent vision of
>> python management that encapsulates both building ad testing yet. For
>> example, should configure/make expect to be run inside of a venv, or
>> should they expect to create and then enter the venv? That's not clear
>> to me yet. I'm simultaneously trying to work out with Peter Maydell how
>> the sphinx dependency should work. Sphinx is presently our only python
>> dependency for our build environment.)
> 
> It's kind of obvious that this can't require user interaction because we
> want ./configure; make to work. So I guess this means the venv needs to
> be set up automatically by configure/make?
> 
>> Perhaps starting with the testing step is a good starting point and we
>> can use an implicit dependency on a `make develop` style step so it
>> happens automatically.
>>
>> (But perhaps keeping it as a standalone target that CAN be invoked
>> manually would be nice if you want to do some more intensive debugging
>> or development of new tests.)
> 
> Yes. And you'll have many dependencies on it, so it would be a separate
> target anyway.
> 
>>> Doing it automatically also means that we have to keep things local to
>>> the QEMU directory rather than installing them globally into the user
>>> directory. This is desirable anyway: Most of us deal with more than one
>>> QEMU source tree, so conflicts would be inevitable.
>>
>> I think it should be easy enough to put the VENV in the build directory
>> to prevent cross-contamination.
> 
> Sure. I'm not overly familiar with all of this, but I guess my point was
> just that a venv is needed rather than a global installation into the
> user directory. If nobody ever suggested the latter, blame the
> misunderstanding on my non-existent experience with more complex Python
> setups.
> 

Python doesn't make it easy to understand, I think.

I'll head along in this direction: We want testing to use a venv that
exists in the build directory and we want to automate its creation and
usage.

I am still working out the role of Python/VENVs at configure time with
Peter Maydell in another thread which may answer the other half of the
equation for me.

--js

> Kevin
> 



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

end of thread, other threads:[~2020-06-19 17:17 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-03  0:15 [PATCH 0/7] python: create installable package John Snow
2020-06-03  0:15 ` [PATCH 1/7] python/qemu: create qemu.lib module John Snow
2020-06-05 12:33   ` Vladimir Sementsov-Ogievskiy
2020-06-03  0:15 ` [PATCH 2/7] python/qemu: formalize as package John Snow
2020-06-05 14:40   ` Vladimir Sementsov-Ogievskiy
2020-06-05 15:42     ` John Snow
2020-06-05 19:23     ` John Snow
2020-06-03  0:15 ` [PATCH 3/7] python/qemu: add README.rst John Snow
2020-06-05 14:56   ` Vladimir Sementsov-Ogievskiy
2020-06-05 16:18     ` John Snow
2020-06-03  0:15 ` [PATCH 4/7] python/qemu: Add pipenv support John Snow
2020-06-05 15:37   ` Vladimir Sementsov-Ogievskiy
2020-06-05 15:54     ` John Snow
2020-06-05 16:21   ` Vladimir Sementsov-Ogievskiy
2020-06-05 17:11     ` John Snow
2020-06-06  5:31       ` Vladimir Sementsov-Ogievskiy
2020-06-03  0:15 ` [PATCH 5/7] python/qemu: add pylint to pipenv John Snow
2020-06-03  0:15 ` [PATCH 6/7] python/qemu: Add flake8 " John Snow
2020-06-03  0:15 ` [PATCH 7/7] python/qemu: add mypy " John Snow
2020-06-06  5:53 ` [PATCH 0/7] python: create installable package Vladimir Sementsov-Ogievskiy
2020-06-08 14:14   ` John Snow
2020-06-17 19:52 ` Cleber Rosa
2020-06-17 20:27   ` John Snow
2020-06-18  9:23     ` Kevin Wolf
2020-06-19 15:04       ` John Snow
2020-06-19 16:44         ` Kevin Wolf
2020-06-19 17:14           ` John Snow
2020-06-19 15:09       ` Philippe Mathieu-Daudé
2020-06-19 15:15     ` Philippe Mathieu-Daudé
2020-06-19 16:10       ` 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.