Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37911344
en ru br
Репозитории ALT

Группа :: Development/Python3
Пакет: python3-module-virtualenv

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: python3-module-virtualenv-20.24.3-alt.patch
Скачать


 src/virtualenv/seed/embed/base_embed.py            |   2 +-
 src/virtualenv/seed/wheels/embed/__init__.py       | 117 ++++++++++++++++++++-
 tests/integration/test_run_int.py                  |   4 +
 tests/integration/test_zipapp.py                   |   5 +
 .../seed/embed/test_bootstrap_link_via_app_data.py |   3 +
 tests/unit/seed/wheels/test_acquire_find_wheel.py  |  20 ++++
 6 files changed, 148 insertions(+), 3 deletions(-)
diff --git a/src/virtualenv/seed/embed/base_embed.py b/src/virtualenv/seed/embed/base_embed.py
index 5ff2c84..ac18334 100644
--- a/src/virtualenv/seed/embed/base_embed.py
+++ b/src/virtualenv/seed/embed/base_embed.py
@@ -6,7 +6,7 @@ from pathlib import Path
 from virtualenv.seed.seeder import Seeder
 from virtualenv.seed.wheels import Version
 
-PERIODIC_UPDATE_ON_BY_DEFAULT = True
+PERIODIC_UPDATE_ON_BY_DEFAULT = False
 
 
 class BaseEmbed(Seeder, metaclass=ABCMeta):
diff --git a/src/virtualenv/seed/wheels/embed/__init__.py b/src/virtualenv/seed/wheels/embed/__init__.py
index 0d87e4b..e883c03 100644
--- a/src/virtualenv/seed/wheels/embed/__init__.py
+++ b/src/virtualenv/seed/wheels/embed/__init__.py
@@ -2,9 +2,14 @@ from __future__ import annotations
 
 from pathlib import Path
 
+from operator import attrgetter
+import re
+import sys
+import sysconfig
+import subprocess
+
 from virtualenv.seed.wheels.util import Wheel
 
-BUNDLE_FOLDER = Path(__file__).absolute().parent
 BUNDLE_SUPPORT = {
     "3.7": {
         "pip": "pip-23.2.1-py3-none-any.whl",
@@ -40,8 +45,116 @@ BUNDLE_SUPPORT = {
 MAX = "3.7"
 
 
+def get_bundle_folder(for_py_version=None):
+    """Return path of the system seed wheels"""
+    global _BUNDLE_FOLDER_CACHE
+
+    try:
+        return _BUNDLE_FOLDER_CACHE[for_py_version]
+    except KeyError:
+        pass
+
+    version_pattern = r"^\d+\.\d+$"
+    if for_py_version and not re.match(version_pattern, for_py_version):
+        raise ValueError(
+            f"Unsupported value for for_py_version: '{for_py_version}', "
+            f"expected regex: '{version_pattern}'"
+        )
+    if for_py_version is None:
+        for_py_version_major = str(sys.version_info.major)
+    else:
+        for_py_version_major = for_py_version[0]
+
+    # assume all system Pythons were configured with the same "scripts" path
+    system_python = Path(sysconfig.get_path(name="scripts")) / (
+        f"python{for_py_version_major}"
+    )
+    cmd = [
+        system_python,
+        "-c",
+        (
+            "import os, sys, system_seed_wheels;"
+            "sys.stdout.write(os.path.dirname(system_seed_wheels.__file__))"
+        ),
+    ]
+    try:
+        _BUNDLE_FOLDER_CACHE[for_py_version] = Path(
+            subprocess.check_output(cmd, text=True)
+        )
+        return _BUNDLE_FOLDER_CACHE[for_py_version]
+    except subprocess.CalledProcessError as e:
+        raise RuntimeError(
+            "Cannot find the folder with system seed wheels. "
+            "Please, install system-seed-wheels package if "
+            f"it has support for your Python interpreter: '{system_python}'"
+        ) from e
+
+
+class BundleSupport:
+    SEED_NAMES = ("pip", "setuptools", "wheel")
+
+    def __init__(self, for_py_version=None):
+        self._system_seed_wheels = None
+        if for_py_version is None:
+            self.for_py_version = "{}.{}".format(*sys.version_info[0:2])
+        else:
+            self.for_py_version = for_py_version
+        self.wheels_dir = get_bundle_folder(for_py_version)
+
+    def discover_wheel(self, distribution):
+        """based on virtualenv.seed.wheels.util.discover_wheels"""
+        wheels = []
+        for filename in self.wheels_dir.iterdir():
+            wheel = Wheel.from_path(filename)
+            if wheel and wheel.distribution == distribution:
+                wheels.append(wheel)
+        sorted_wheels = sorted(
+            wheels,
+            key=attrgetter("version_tuple", "distribution"),
+            reverse=True,
+        )
+        if not sorted_wheels:
+            raise RuntimeError(
+                f"Wheel for distribution: '{distribution}' not found on path: "
+                f"'{self.wheels_dir}'"
+            )
+        return sorted_wheels[0].name
+
+    @property
+    def system_seed_wheels(self):
+        if self._system_seed_wheels is None:
+            wheels_names = {}
+            for distr in self.SEED_NAMES:
+                wheels_names[distr] = self.discover_wheel(distr)
+            self._system_seed_wheels = {
+                self.for_py_version: dict(wheels_names)
+            }
+
+        return self._system_seed_wheels
+
+    def __getitem__(self, key):
+        return self.system_seed_wheels[self.for_py_version]
+
+    def get(self, key, default=None):
+        return self.system_seed_wheels[self.for_py_version]
+
+    def items(self):
+        return self.system_seed_wheels.items()
+
+    def keys(self):
+        return self.system_seed_wheels.keys()
+
+
+_BUNDLE_FOLDER_CACHE = {}
+# defined only for self tests, which only check the current interpreter
+BUNDLE_FOLDER = get_bundle_folder()
+BUNDLE_SUPPORT = BundleSupport()
+
+
 def get_embed_wheel(distribution, for_py_version):
-    path = BUNDLE_FOLDER / (BUNDLE_SUPPORT.get(for_py_version, {}) or BUNDLE_SUPPORT[MAX]).get(distribution)
+    path = get_bundle_folder(for_py_version) / (
+        BundleSupport(for_py_version).get(for_py_version, {})
+    ).get(distribution)
     return Wheel.from_path(path)
 
 
diff --git a/tests/integration/test_run_int.py b/tests/integration/test_run_int.py
index e1dc6d3..bb459c7 100644
--- a/tests/integration/test_run_int.py
+++ b/tests/integration/test_run_int.py
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import os
 from typing import TYPE_CHECKING
 
 import pytest
@@ -12,6 +13,9 @@ if TYPE_CHECKING:
     from pathlib import Path
 
 
+@pytest.mark.skipif(
+    "NO_INTERNET" in os.environ, reason="Requires internet connection",
+)
 @pytest.mark.skipif(IS_PYPY, reason="setuptools distutils patching does not work")
 def test_app_data_pinning(tmp_path: Path) -> None:
     version = "23.1"
diff --git a/tests/integration/test_zipapp.py b/tests/integration/test_zipapp.py
index 5bcddf5..ed47de1 100644
--- a/tests/integration/test_zipapp.py
+++ b/tests/integration/test_zipapp.py
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import os
 import shutil
 import subprocess
 from contextlib import suppress
@@ -14,6 +15,10 @@ from virtualenv.run import cli_run
 HERE = Path(__file__).parent
 CURRENT = PythonInfo.current_system()
 
+pytestmark = pytest.mark.skipif(
+    "NO_INTERNET" in os.environ, reason="Requires internet connection",
+)
+
 
 @pytest.fixture(scope="session")
 def zipapp_build_env(tmp_path_factory):
diff --git a/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py b/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
index 7db52e1..16895a5 100644
--- a/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
+++ b/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
@@ -25,6 +25,9 @@ if TYPE_CHECKING:
 
 @pytest.mark.slow()
 @pytest.mark.parametrize("copies", [False, True] if fs_supports_symlink() else [True])
+@pytest.mark.skipif(
+    "NO_INTERNET" in os.environ, reason="Requires internet connection"
+)
 def test_seed_link_via_app_data(tmp_path, coverage_env, current_fastest, copies):
     current = PythonInfo.current_system()
     bundle_ver = BUNDLE_SUPPORT[current.version_release_str]
diff --git a/tests/unit/seed/wheels/test_acquire_find_wheel.py b/tests/unit/seed/wheels/test_acquire_find_wheel.py
index 7822849..a13466e 100644
--- a/tests/unit/seed/wheels/test_acquire_find_wheel.py
+++ b/tests/unit/seed/wheels/test_acquire_find_wheel.py
@@ -27,3 +27,23 @@ def test_find_exact(for_py_version):
 def test_find_bad_spec():
     with pytest.raises(ValueError, match="bad"):
         find_compatible_in_house("setuptools", "bad", MAX, BUNDLE_FOLDER)
+
+
+# ALT tests
+def test_find_python2():
+    """Python2 is not supported"""
+    with pytest.raises(FileNotFoundError):
+        get_embed_wheel("setuptools", "2.7")
+
+
+def test_find_python4():
+    """Future Python4 is not yet supported"""
+    with pytest.raises(FileNotFoundError):
+        get_embed_wheel("setuptools", "4.0")
+
+
+def test_wrong_version():
+    """Python version format"""
+    with pytest.raises(ValueError) as e:
+        get_embed_wheel("setuptools", "123")
+    assert "Unsupported value for for_py_version:" in str(e.value)
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin