From 3f22c840a0b26dae8dd09985501eaa33846f063c Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Thu, 27 Oct 2022 11:50:54 +0200 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 --- 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 | 3 +++ src/virtualenv/util/path/_system_wheels.py | 27 +++++++++++++++++++ 7 files changed, 52 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 6d22b71..19d1791 100644 --- a/src/virtualenv/run/__init__.py +++ b/src/virtualenv/run/__init__.py @@ -87,8 +87,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 f29110b..07649c2 100644 --- a/src/virtualenv/seed/embed/base_embed.py +++ b/src/virtualenv/seed/embed/base_embed.py @@ -3,8 +3,9 @@ from pathlib import Path from ..seeder import Seeder from ..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, metaclass=ABCMeta): @@ -27,6 +28,15 @@ class BaseEmbed(Seeder, metaclass=ABCMeta): 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): return { @@ -105,6 +115,10 @@ class BaseEmbed(Seeder, metaclass=ABCMeta): 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 2ca9438..339295f 100644 --- a/src/virtualenv/seed/embed/pip_invoke.py +++ b/src/virtualenv/seed/embed/pip_invoke.py @@ -15,6 +15,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 f31ecf6..d7a0f5a 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 @@ -37,6 +37,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 21fde34..4370b0d 100644 --- a/src/virtualenv/seed/wheels/acquire.py +++ b/src/virtualenv/seed/wheels/acquire.py @@ -24,11 +24,12 @@ def get_wheel(distribution, version, for_py_version, search_dirs, download, app_ if download and wheel is None and version != Version.embed: # 2. download from the internet + from virtualenv.util.path._system_wheels import get_system_wheels_paths wheel = download_wheel( distribution=distribution, version_spec=Version.as_version_spec(version), for_py_version=for_py_version, - search_dirs=search_dirs, + search_dirs=get_system_wheels_paths(sys), app_data=app_data, to_folder=app_data.house, env=env, diff --git a/src/virtualenv/seed/wheels/embed/__init__.py b/src/virtualenv/seed/wheels/embed/__init__.py index 782051a..71ec712 100644 --- a/src/virtualenv/seed/wheels/embed/__init__.py +++ b/src/virtualenv/seed/wheels/embed/__init__.py @@ -52,8 +52,11 @@ BUNDLE_SUPPORT = { } MAX = "3.12" +# 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..fc7e942 --- /dev/null +++ b/src/virtualenv/util/path/_system_wheels.py @@ -0,0 +1,27 @@ +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 + # The EL 9 main Python has just 3 (this is the %{python3_pkgversion} RPM macro) + if interpreter.version_info[:2] == (3, 9): + python3_pkgversion = "3" + else: + python3_pkgversion = "{0.major}.{0.minor}".format(interpreter.version_info) + wheels_dir = Path(f"/usr/share/python{python3_pkgversion}-wheels") + if wheels_dir.exists(): + yield wheels_dir -- 2.47.0