From da9ce1c9d7d422e310d79d58a8b7ed07cbc781d1 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Thu, 9 Feb 2023 15:13:36 +0100
Subject: [PATCH] RPM wheels
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Miro HronĨok <miro@hroncok.cz>
---
src/virtualenv/run/__init__.py | 5 +++--
src/virtualenv/seed/embed/base_embed.py | 16 +++++++++++++-
src/virtualenv/seed/embed/pip_invoke.py | 1 +
.../seed/embed/via_app_data/via_app_data.py | 1 +
src/virtualenv/seed/wheels/acquire.py | 3 ++-
src/virtualenv/seed/wheels/embed/__init__.py | 4 ++++
src/virtualenv/util/path/_system_wheels.py | 22 +++++++++++++++++++
7 files changed, 48 insertions(+), 4 deletions(-)
create mode 100644 src/virtualenv/util/path/_system_wheels.py
diff --git a/src/virtualenv/run/__init__.py b/src/virtualenv/run/__init__.py
index 48647ec..80c9d4a 100644
--- a/src/virtualenv/run/__init__.py
+++ b/src/virtualenv/run/__init__.py
@@ -97,8 +97,9 @@ def build_parser_only(args=None):
def handle_extra_commands(options):
if options.upgrade_embed_wheels:
- result = manual_upgrade(options.app_data, options.env)
- raise SystemExit(result)
+ # result = manual_upgrade(options.app_data, options.env)
+ logging.warning("virtualenv installed from the RPM package uses wheels from RPM packages as well. Updating them via virtualenv is not possible. The RPM packaged wheels are updated together with other RPM packages of the system.")
+ raise SystemExit(1)
def load_app_data(args, parser, options):
diff --git a/src/virtualenv/seed/embed/base_embed.py b/src/virtualenv/seed/embed/base_embed.py
index 864cc49..4586f40 100644
--- a/src/virtualenv/seed/embed/base_embed.py
+++ b/src/virtualenv/seed/embed/base_embed.py
@@ -5,8 +5,9 @@ from pathlib import Path
from virtualenv.seed.seeder import Seeder
from virtualenv.seed.wheels import Version
+from virtualenv.util.path._system_wheels import get_system_wheels_paths
-PERIODIC_UPDATE_ON_BY_DEFAULT = True
+PERIODIC_UPDATE_ON_BY_DEFAULT = False
class BaseEmbed(Seeder, ABC):
@@ -28,6 +29,15 @@ class BaseEmbed(Seeder, ABC):
if not self.distribution_to_versions():
self.enabled = False
+
+ if "embed" in (self.pip_version, self.setuptools_version, self.wheel_version):
+ raise RuntimeError(
+ "Embedded wheels are not available if virtualenv "
+ "is installed from the RPM package.\nEither install "
+ "virtualenv from PyPI (via pip) or use 'bundle' "
+ "version which uses the system-wide pip, setuptools "
+ "and wheel wheels provided also by RPM packages."
+ )
@classmethod
def distributions(cls) -> dict[str, Version]:
@@ -112,6 +122,10 @@ class BaseEmbed(Seeder, ABC):
result += f" {distribution}{ver},"
return result[:-1] + ")"
+ def insert_system_wheels_paths(self, creator):
+ system_wheels_paths = get_system_wheels_paths(creator.interpreter)
+ self.extra_search_dir = list(system_wheels_paths) + self.extra_search_dir
+
__all__ = [
"BaseEmbed",
diff --git a/src/virtualenv/seed/embed/pip_invoke.py b/src/virtualenv/seed/embed/pip_invoke.py
index 815753c..5423c9f 100644
--- a/src/virtualenv/seed/embed/pip_invoke.py
+++ b/src/virtualenv/seed/embed/pip_invoke.py
@@ -16,6 +16,7 @@ class PipInvoke(BaseEmbed):
def run(self, creator):
if not self.enabled:
return
+ self.insert_system_wheels_paths(creator)
for_py_version = creator.interpreter.version_release_str
with self.get_pip_install_cmd(creator.exe, for_py_version) as cmd:
env = pip_wheel_env_run(self.extra_search_dir, self.app_data, self.env)
diff --git a/src/virtualenv/seed/embed/via_app_data/via_app_data.py b/src/virtualenv/seed/embed/via_app_data/via_app_data.py
index 7e58bfc..e236319 100644
--- a/src/virtualenv/seed/embed/via_app_data/via_app_data.py
+++ b/src/virtualenv/seed/embed/via_app_data/via_app_data.py
@@ -39,6 +39,7 @@ class FromAppData(BaseEmbed):
def run(self, creator):
if not self.enabled:
return
+ self.insert_system_wheels_paths(creator)
with self._get_seed_wheels(creator) as name_to_whl:
pip_version = name_to_whl["pip"].version_tuple if "pip" in name_to_whl else None
installer_class = self.installer_class(pip_version)
diff --git a/src/virtualenv/seed/wheels/acquire.py b/src/virtualenv/seed/wheels/acquire.py
index 8b3ddd8..7a2a4e5 100644
--- a/src/virtualenv/seed/wheels/acquire.py
+++ b/src/virtualenv/seed/wheels/acquire.py
@@ -106,13 +106,14 @@ def find_compatible_in_house(distribution, version_spec, for_py_version, in_fold
def pip_wheel_env_run(search_dirs, app_data, env):
+ from virtualenv.util.path._system_wheels import get_system_wheels_paths
env = env.copy()
env.update({"PIP_USE_WHEEL": "1", "PIP_USER": "0", "PIP_NO_INPUT": "1"})
wheel = get_wheel(
distribution="pip",
version=None,
for_py_version=f"{sys.version_info.major}.{sys.version_info.minor}",
- search_dirs=search_dirs,
+ search_dirs=get_system_wheels_paths(sys),
download=False,
app_data=app_data,
do_periodic_update=False,
diff --git a/src/virtualenv/seed/wheels/embed/__init__.py b/src/virtualenv/seed/wheels/embed/__init__.py
index f068efc..fc044f1 100644
--- a/src/virtualenv/seed/wheels/embed/__init__.py
+++ b/src/virtualenv/seed/wheels/embed/__init__.py
@@ -50,7 +50,11 @@ BUNDLE_SUPPORT = {
MAX = "3.7"
+# Redefined here because bundled wheels are removed in RPM build
+BUNDLE_SUPPORT = None
+
def get_embed_wheel(distribution, for_py_version):
+ return None # BUNDLE_SUPPORT == None anyway
path = BUNDLE_FOLDER / (BUNDLE_SUPPORT.get(for_py_version, {}) or BUNDLE_SUPPORT[MAX]).get(distribution)
return Wheel.from_path(path)
diff --git a/src/virtualenv/util/path/_system_wheels.py b/src/virtualenv/util/path/_system_wheels.py
new file mode 100644
index 0000000..f3fd9b1
--- /dev/null
+++ b/src/virtualenv/util/path/_system_wheels.py
@@ -0,0 +1,22 @@
+from pathlib import Path
+from subprocess import check_output, CalledProcessError
+
+
+def get_system_wheels_paths(interpreter):
+ # ensurepip wheels
+ # We need subprocess here to check ensurepip with the Python we are creating
+ # a new virtual environment for
+ executable = interpreter.executable
+ try:
+ ensurepip_path = check_output((executable, "-u", "-c", 'import ensurepip; print(ensurepip.__path__[0])'), universal_newlines=True)
+ ensurepip_path = Path(ensurepip_path.strip()) / "_bundled"
+ except CalledProcessError:
+ pass
+ else:
+ if ensurepip_path.is_dir():
+ yield ensurepip_path
+
+ # Standard wheels path
+ wheels_dir = Path("/usr/share/python-wheels")
+ if wheels_dir.exists():
+ yield wheels_dir
--
2.46.2