[PATCH v5 04/16] python/mkvenv: add mechanism to install local package(s)

John Snow posted 16 patches 3 days, 9 hours ago
Maintainers: "Alex Bennée" <alex.bennee@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Thomas Huth <thuth@redhat.com>, Ed Maste <emaste@freebsd.org>, Li-Wen Hsu <lwhsu@freebsd.org>, Yonggang Luo <luoyonggang@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, John Snow <jsnow@redhat.com>, Cleber Rosa <crosa@redhat.com>, Maksim Davydov <davydov-max@yandex-team.ru>, Markus Armbruster <armbru@redhat.com>, Mauro Carvalho Chehab <mchehab+huawei@kernel.org>, Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>, Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>
[PATCH v5 04/16] python/mkvenv: add mechanism to install local package(s)
Posted by John Snow 3 days, 9 hours ago
Currently, we "implicitly" install the local 'qemu' python package for
'make check-venv' with some logic inside tests/Makefile.include. I would
like to make this installation explicit in pythondeps.toml instead.

This patch adds a path constraint that can be used in lieu of version
constraints to specify that a package should be installed from the
source tree instead of from PyPI or vendored packages. This is done to
allow us to install the python packages hosted inside of the tree while
also processing dependencies; i.e. so that our "qemu" package can
specify that it needs "qemu.qmp", which soon will not be included in
qemu.git.

This also has the benefit of being able to specify in a declarative
configuration file that our pyvenv environment *will* have our local
python packages installed and available without any PYTHONPATH hacks,
which should simplify iotests, device-crash-test and functional tests
without needing to manage local inclusion paths in environment
variables.

On the downsides, installing packages through mkvenv/ensuregroup means
that there are extra steps we need to take in order to install a local
package *offline*; namely we must disable build isolation (so we have
access to setuptools) and we must also include python3-wheel in QEMU's
build dependencies in order for "make check" to run successfully when in
an offline, isolated environment. These extra dependencies are handled
in a forthcoming commit; for now, nothing is utilizing this new pathway.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 python/scripts/mkvenv.py | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py
index b4662d33e6e..8ed6a354505 100644
--- a/python/scripts/mkvenv.py
+++ b/python/scripts/mkvenv.py
@@ -662,6 +662,7 @@ def pip_install(
     args: Sequence[str],
     online: bool = False,
     wheels_dir: Optional[Union[str, Path]] = None,
+    env: Optional[Dict[str, str]] = None,
 ) -> None:
     """
     Use pip to install a package or package(s) as specified in @args.
@@ -687,6 +688,7 @@ def pip_install(
     full_args += list(args)
     subprocess.run(
         full_args,
+        env=env,
         check=True,
     )
 
@@ -733,9 +735,14 @@ def _do_ensure(
     :param wheels_dir: If specified, search this path for packages.
     """
     absent = []
+    local_packages = []
     present = []
     canary = None
     for name, info in group.items():
+        if "path" in info:
+            pkgpath = Path(__file__).parents[2].joinpath(info["path"])
+            local_packages.append(str(pkgpath))
+            continue
         constraint = _make_version_constraint(info, False)
         matcher = Matcher(name + constraint)
         print(f"mkvenv: checking for {matcher}", file=sys.stderr)
@@ -770,15 +777,33 @@ def _do_ensure(
             print(f"mkvenv: installing {', '.join(absent)}", file=sys.stderr)
             try:
                 pip_install(args=absent, online=online, wheels_dir=wheels_dir)
-                return None
+                absent = []
             except subprocess.CalledProcessError:
                 pass
 
-        return diagnose(
-            absent[0],
-            online,
-            wheels_dir,
-            canary,
+        if absent:
+            return diagnose(
+                absent[0],
+                online,
+                wheels_dir,
+                canary,
+            )
+
+    # Handle local packages separately and last so we can use different
+    # installation arguments (-e), and so that any dependencies that may
+    # be covered above will be handled according to the depfile
+    # specifications.
+    if local_packages:
+        print(f"mkvenv: installing {', '.join(local_packages)}",
+              file=sys.stderr)
+        env = dict(os.environ)
+        env['PIP_CONFIG_SETTINGS'] = "editable_mode=compat"
+        pip_install(
+            args=["--no-build-isolation",
+                  "-e"] + local_packages,
+            online=online,
+            wheels_dir=wheels_dir,
+            env=env,
         )
 
     return None
-- 
2.52.0
Re: [PATCH v5 04/16] python/mkvenv: add mechanism to install local package(s)
Posted by Thomas Huth 2 days, 21 hours ago
On 03/02/2026 21.34, John Snow wrote:
> Currently, we "implicitly" install the local 'qemu' python package for
> 'make check-venv' with some logic inside tests/Makefile.include. I would
> like to make this installation explicit in pythondeps.toml instead.
> 
> This patch adds a path constraint that can be used in lieu of version
> constraints to specify that a package should be installed from the
> source tree instead of from PyPI or vendored packages. This is done to
> allow us to install the python packages hosted inside of the tree while
> also processing dependencies; i.e. so that our "qemu" package can
> specify that it needs "qemu.qmp", which soon will not be included in
> qemu.git.
> 
> This also has the benefit of being able to specify in a declarative
> configuration file that our pyvenv environment *will* have our local
> python packages installed and available without any PYTHONPATH hacks,
> which should simplify iotests, device-crash-test and functional tests
> without needing to manage local inclusion paths in environment
> variables.
> 
> On the downsides, installing packages through mkvenv/ensuregroup means
> that there are extra steps we need to take in order to install a local
> package *offline*; namely we must disable build isolation (so we have
> access to setuptools) and we must also include python3-wheel in QEMU's
> build dependencies in order for "make check" to run successfully when in
> an offline, isolated environment. These extra dependencies are handled
> in a forthcoming commit; for now, nothing is utilizing this new pathway.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   python/scripts/mkvenv.py | 37 +++++++++++++++++++++++++++++++------
>   1 file changed, 31 insertions(+), 6 deletions(-)

Reviewed-by: Thomas Huth <thuth@redhat.com>