summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchrysle <fritzihab@posteo.de>2023-04-28 01:36:03 +0200
committerGitHub <noreply@github.com>2023-04-27 16:36:03 -0700
commitfd93dd79be89b21e6e9d43ca2dd1b02b811f6d6f (patch)
tree89c53dd6b596d5ff6da56bb814b57b735e8c8f24
parent89f80b8fb18a15243d5f0b5e288f62bc86538a80 (diff)
downloadvirtualenv-fd93dd79be89b21e6e9d43ca2dd1b02b811f6d6f.tar.gz
3.12 support and no setuptools/wheel on 3.12+ (#2558)
-rw-r--r--.github/workflows/check.yml1
-rw-r--r--docs/changelog/2487.feature.rst6
-rw-r--r--docs/changelog/2558.feature.rst1
-rw-r--r--docs/render_cli.py10
-rw-r--r--docs/user_guide.rst5
-rw-r--r--pyproject.toml6
-rw-r--r--src/virtualenv/activation/python/__init__.py3
-rw-r--r--src/virtualenv/seed/embed/base_embed.py17
-rw-r--r--src/virtualenv/util/path/_sync.py4
-rw-r--r--tests/conftest.py31
-rw-r--r--tests/integration/test_run_int.py6
-rw-r--r--tests/unit/config/test___main__.py5
-rw-r--r--tests/unit/create/test_creator.py26
-rw-r--r--tests/unit/discovery/py_info/test_py_info.py2
-rw-r--r--tests/unit/discovery/windows/conftest.py2
-rw-r--r--tests/unit/seed/embed/test_base_embed.py13
-rw-r--r--tests/unit/seed/embed/test_bootstrap_link_via_app_data.py8
-rw-r--r--tests/unit/seed/wheels/test_acquire.py13
-rw-r--r--tests/unit/seed/wheels/test_periodic_update.py53
19 files changed, 140 insertions, 72 deletions
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 19b37fc..81916ad 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -19,6 +19,7 @@ jobs:
fail-fast: false
matrix:
py:
+ - "3.12.0-alpha.7"
- "3.11"
- "3.10"
- "3.9"
diff --git a/docs/changelog/2487.feature.rst b/docs/changelog/2487.feature.rst
new file mode 100644
index 0000000..12cc896
--- /dev/null
+++ b/docs/changelog/2487.feature.rst
@@ -0,0 +1,6 @@
+Do not install ``wheel`` and ``setuptools`` seed packages for Python 3.12+. To restore the old behaviour use:
+
+- for ``wheel`` use ``VIRTUALENV_WHEEL=bundle`` environment variable or ``--wheel=bundle`` CLI flag,
+- for ``setuptools`` use ``VIRTUALENV_SETUPTOOLS=bundle`` environment variable or ``--setuptools=bundle`` CLI flag.
+
+By :user:`chrysle`.
diff --git a/docs/changelog/2558.feature.rst b/docs/changelog/2558.feature.rst
new file mode 100644
index 0000000..58b627a
--- /dev/null
+++ b/docs/changelog/2558.feature.rst
@@ -0,0 +1 @@
+3.12 support - by :user:`gaborbernat`.
diff --git a/docs/render_cli.py b/docs/render_cli.py
index 5e76611..76cecd1 100644
--- a/docs/render_cli.py
+++ b/docs/render_cli.py
@@ -180,15 +180,7 @@ class CliTable(SphinxDirective):
content = row.help[: row.help.index("(") - 1]
else:
content = row.help
- if name in ("--setuptools", "--pip", "--wheel"):
- text = row.help
- at = text.index(" bundle ")
- help_body = n.paragraph("")
- help_body += n.Text(text[: at + 1])
- help_body += n.literal(text="bundle")
- help_body += n.Text(text[at + 7 :])
- else:
- help_body = n.paragraph("", "", n.Text(content))
+ help_body = n.paragraph("", "", n.Text(content))
if row.choices is not None:
help_body += n.Text("; choice of: ")
first = True
diff --git a/docs/user_guide.rst b/docs/user_guide.rst
index 3215ed6..9a2c26f 100644
--- a/docs/user_guide.rst
+++ b/docs/user_guide.rst
@@ -118,8 +118,9 @@ at the moment has two types of virtual environments:
Seeders
-------
These will install for you some seed packages (one or more of: :pypi:`pip`, :pypi:`setuptools`, :pypi:`wheel`) that
-enables you to install additional python packages into the created virtual environment (by invoking pip). There are two
-main seed mechanism available:
+enables you to install additional python packages into the created virtual environment (by invoking pip). Installing
+:pypi:`setuptools` and :pypi:`wheel` is disabled by default on Python 3.12+ environments. There are two
+main seed mechanisms available:
- ``pip`` - this method uses the bundled pip with virtualenv to install the seed packages (note, a new child process
needs to be created to do this, which can be expensive especially on Windows).
diff --git a/pyproject.toml b/pyproject.toml
index 92f4b18..5a883da 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -57,10 +57,12 @@ optional-dependencies.test = [
"packaging>=23.1",
"pytest>=7.3.1",
"pytest-env>=0.8.1",
- "pytest-freezegun>=0.4.2",
+ 'pytest-freezegun>=0.4.2; platform_python_implementation == "PyPy"',
"pytest-mock>=3.10",
"pytest-randomly>=3.12",
"pytest-timeout>=2.1",
+ "setuptools>=67.7.1",
+ 'time-machine>=2.9; platform_python_implementation == "CPython"',
]
urls.Documentation = "https://virtualenv.pypa.io"
urls.Homepage = "https://github.com/pypa/virtualenv"
@@ -116,7 +118,7 @@ ignore = [
[tool.pytest.ini_options]
markers = ["slow"]
timeout = 600
-addopts = "--tb=auto -ra --showlocals --no-success-flaky-report"
+addopts = "--showlocals --no-success-flaky-report"
env = ["PYTHONIOENCODING=utf-8"]
[tool.coverage]
diff --git a/src/virtualenv/activation/python/__init__.py b/src/virtualenv/activation/python/__init__.py
index 28861f9..ed220dc 100644
--- a/src/virtualenv/activation/python/__init__.py
+++ b/src/virtualenv/activation/python/__init__.py
@@ -13,9 +13,10 @@ class PythonActivator(ViaTemplateActivator):
def replacements(self, creator, dest_folder):
replacements = super().replacements(creator, dest_folder)
lib_folders = OrderedDict((os.path.relpath(str(i), str(dest_folder)), None) for i in creator.libs)
+ lib_folders = os.pathsep.join(lib_folders.keys()).replace("\\", "\\\\") # escape Windows path characters
replacements.update(
{
- "__LIB_FOLDERS__": os.pathsep.join(lib_folders.keys()),
+ "__LIB_FOLDERS__": lib_folders,
"__DECODE_PATH__": "",
},
)
diff --git a/src/virtualenv/seed/embed/base_embed.py b/src/virtualenv/seed/embed/base_embed.py
index 65f2b97..80a3364 100644
--- a/src/virtualenv/seed/embed/base_embed.py
+++ b/src/virtualenv/seed/embed/base_embed.py
@@ -30,18 +30,18 @@ class BaseEmbed(Seeder, metaclass=ABCMeta):
self.enabled = False
@classmethod
- def distributions(cls):
+ def distributions(cls) -> dict[str, Version]:
return {
"pip": Version.bundle,
"setuptools": Version.bundle,
"wheel": Version.bundle,
}
- def distribution_to_versions(self):
+ def distribution_to_versions(self) -> dict[str, str]:
return {
distribution: getattr(self, f"{distribution}_version")
for distribution in self.distributions()
- if getattr(self, f"no_{distribution}") is False
+ if getattr(self, f"no_{distribution}") is False and getattr(self, f"{distribution}_version") != "none"
}
@classmethod
@@ -71,11 +71,13 @@ class BaseEmbed(Seeder, metaclass=ABCMeta):
default=[],
)
for distribution, default in cls.distributions().items():
+ if interpreter.version_info[:2] >= (3, 12) and distribution in {"wheel", "setuptools"}:
+ default = "none"
parser.add_argument(
f"--{distribution}",
dest=distribution,
metavar="version",
- help=f"version of {distribution} to install as seed: embed, bundle or exact version",
+ help=f"version of {distribution} to install as seed: embed, bundle, none or exact version",
default=default,
)
for distribution in cls.distributions():
@@ -94,7 +96,7 @@ class BaseEmbed(Seeder, metaclass=ABCMeta):
default=not PERIODIC_UPDATE_ON_BY_DEFAULT,
)
- def __repr__(self):
+ def __repr__(self) -> str:
result = self.__class__.__name__
result += "("
if self.extra_search_dir:
@@ -103,7 +105,10 @@ class BaseEmbed(Seeder, metaclass=ABCMeta):
for distribution in self.distributions():
if getattr(self, f"no_{distribution}"):
continue
- ver = f"={getattr(self, f'{distribution}_version', None) or 'latest'}"
+ version = getattr(self, f"{distribution}_version", None)
+ if version == "none":
+ continue
+ ver = f"={version or 'latest'}"
result += f" {distribution}{ver},"
return result[:-1] + ")"
diff --git a/src/virtualenv/util/path/_sync.py b/src/virtualenv/util/path/_sync.py
index f0e0173..a81f82b 100644
--- a/src/virtualenv/util/path/_sync.py
+++ b/src/virtualenv/util/path/_sync.py
@@ -3,6 +3,7 @@ from __future__ import annotations
import logging
import os
import shutil
+import sys
from stat import S_IWUSR
@@ -58,7 +59,8 @@ def safe_delete(dest):
else:
raise
- shutil.rmtree(str(dest), ignore_errors=True, onerror=onerror)
+ kwargs = {"onexc" if sys.version_info >= (3, 12) else "onerror": onerror}
+ shutil.rmtree(str(dest), ignore_errors=True, **kwargs)
class _Debug:
diff --git a/tests/conftest.py b/tests/conftest.py
index 72db0d5..800861e 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -12,7 +12,7 @@ import pytest
from virtualenv.app_data import AppDataDiskFolder
from virtualenv.discovery.py_info import PythonInfo
-from virtualenv.info import IS_WIN, fs_supports_symlink
+from virtualenv.info import IS_PYPY, IS_WIN, fs_supports_symlink
from virtualenv.report import LOGGER
@@ -144,22 +144,6 @@ def _ignore_global_config(tmp_path_factory):
yield
-@pytest.fixture(autouse=True, scope="session")
-def _pip_cert(tmp_path_factory):
- # workaround for https://github.com/pypa/pip/issues/8984 - if the certificate is explicitly set no error can happen
- key = "PIP_CERT"
- if key in os.environ:
- yield
- else:
- cert = tmp_path_factory.mktemp("folder") / "cert"
- import pkgutil
-
- cert_data = pkgutil.get_data("pip._vendor.certifi", "cacert.pem")
- cert.write_bytes(cert_data)
- with change_os_environ(key, str(cert)):
- yield
-
-
@pytest.fixture(autouse=True)
def _check_os_environ_stable():
old = os.environ.copy()
@@ -368,3 +352,16 @@ def _skip_if_test_in_system(session_app_data):
current = PythonInfo.current(session_app_data)
if current.system_executable is not None:
pytest.skip("test not valid if run under system")
+
+
+if IS_PYPY:
+
+ @pytest.fixture()
+ def time_freeze(freezer):
+ return freezer.move_to
+
+else:
+
+ @pytest.fixture()
+ def time_freeze(time_machine):
+ return lambda s: time_machine.move_to(s, tick=False)
diff --git a/tests/integration/test_run_int.py b/tests/integration/test_run_int.py
index 36aaf4f..8f4cc16 100644
--- a/tests/integration/test_run_int.py
+++ b/tests/integration/test_run_int.py
@@ -1,5 +1,7 @@
from __future__ import annotations
+from pathlib import Path
+
import pytest
from virtualenv import cli_run
@@ -8,8 +10,8 @@ from virtualenv.util.subprocess import run_cmd
@pytest.mark.skipif(IS_PYPY, reason="setuptools distutils patching does not work")
-def test_app_data_pinning(tmp_path):
- version = "19.3.1"
+def test_app_data_pinning(tmp_path: Path) -> None:
+ version = "23.0"
result = cli_run([str(tmp_path), "--pip", version, "--activators", "", "--seeder", "app-data"])
code, out, _ = run_cmd([str(result.creator.script("pip")), "list", "--disable-pip-version-check"])
assert not code
diff --git a/tests/unit/config/test___main__.py b/tests/unit/config/test___main__.py
index 76c9dfa..a850415 100644
--- a/tests/unit/config/test___main__.py
+++ b/tests/unit/config/test___main__.py
@@ -2,6 +2,7 @@ from __future__ import annotations
import re
import sys
+from pathlib import Path
from subprocess import PIPE, Popen, check_output
import pytest
@@ -59,8 +60,8 @@ def test_fail_with_traceback(raise_on_session_done, tmp_path, capsys):
@pytest.mark.usefixtures("session_app_data")
-def test_session_report_full(tmp_path, capsys):
- run_with_catch([str(tmp_path)])
+def test_session_report_full(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
+ run_with_catch([str(tmp_path), "--setuptools", "bundle", "--wheel", "bundle"])
out, err = capsys.readouterr()
assert err == ""
lines = out.splitlines()
diff --git a/tests/unit/create/test_creator.py b/tests/unit/create/test_creator.py
index 54e8896..8b33729 100644
--- a/tests/unit/create/test_creator.py
+++ b/tests/unit/create/test_creator.py
@@ -364,7 +364,19 @@ def test_create_long_path(tmp_path):
@pytest.mark.parametrize("creator", sorted(set(PythonInfo.current_system().creators().key_to_class) - {"builtin"}))
@pytest.mark.usefixtures("session_app_data")
def test_create_distutils_cfg(creator, tmp_path, monkeypatch):
- result = cli_run([str(tmp_path / "venv"), "--activators", "", "--creator", creator])
+ result = cli_run(
+ [
+ str(tmp_path / "venv"),
+ "--activators",
+ "",
+ "--creator",
+ creator,
+ "--setuptools",
+ "bundle",
+ "--wheel",
+ "bundle",
+ ],
+ )
app = Path(__file__).parent / "console_app"
dest = tmp_path / "console_app"
@@ -417,7 +429,9 @@ def list_files(path):
def test_zip_importer_can_import_setuptools(tmp_path):
"""We're patching the loaders so might fail on r/o loaders, such as zipimporter on CPython<3.8"""
- result = cli_run([str(tmp_path / "venv"), "--activators", "", "--no-pip", "--no-wheel", "--copies"])
+ result = cli_run(
+ [str(tmp_path / "venv"), "--activators", "", "--no-pip", "--no-wheel", "--copies", "--setuptools", "bundle"],
+ )
zip_path = tmp_path / "site-packages.zip"
with zipfile.ZipFile(str(zip_path), "w", zipfile.ZIP_DEFLATED) as zip_handler:
lib = str(result.creator.purelib)
@@ -451,6 +465,7 @@ def test_no_preimport_threading(tmp_path):
out = subprocess.check_output(
[str(session.creator.exe), "-c", r"import sys; print('\n'.join(sorted(sys.modules)))"],
text=True,
+ encoding="utf-8",
)
imported = set(out.splitlines())
assert "threading" not in imported
@@ -467,6 +482,7 @@ def test_pth_in_site_vs_python_path(tmp_path):
out = subprocess.check_output(
[str(session.creator.exe), "-c", r"import sys; print(sys.testpth)"],
text=True,
+ encoding="utf-8",
)
assert out == "ok\n"
# same with $PYTHONPATH pointing to site_packages
@@ -479,6 +495,7 @@ def test_pth_in_site_vs_python_path(tmp_path):
[str(session.creator.exe), "-c", r"import sys; print(sys.testpth)"],
text=True,
env=env,
+ encoding="utf-8",
)
assert out == "ok\n"
@@ -492,6 +509,7 @@ def test_getsitepackages_system_site(tmp_path):
out = subprocess.check_output(
[str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
text=True,
+ encoding="utf-8",
)
site_packages = ast.literal_eval(out)
@@ -506,6 +524,7 @@ def test_getsitepackages_system_site(tmp_path):
out = subprocess.check_output(
[str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
text=True,
+ encoding="utf-8",
)
site_packages = [str(Path(i).resolve()) for i in ast.literal_eval(out)]
@@ -531,6 +550,7 @@ def test_get_site_packages(tmp_path):
out = subprocess.check_output(
[str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
text=True,
+ encoding="utf-8",
)
site_packages = ast.literal_eval(out)
@@ -569,7 +589,7 @@ def test_python_path(monkeypatch, tmp_path, python_path_on):
if flag:
cmd.append(flag)
cmd.extend(["-c", "import json; import sys; print(json.dumps(sys.path))"])
- return [i if case_sensitive else i.lower() for i in json.loads(subprocess.check_output(cmd))]
+ return [i if case_sensitive else i.lower() for i in json.loads(subprocess.check_output(cmd, encoding="utf-8"))]
monkeypatch.delenv("PYTHONPATH", raising=False)
base = _get_sys_path()
diff --git a/tests/unit/discovery/py_info/test_py_info.py b/tests/unit/discovery/py_info/test_py_info.py
index 639fbaa..f839e22 100644
--- a/tests/unit/discovery/py_info/test_py_info.py
+++ b/tests/unit/discovery/py_info/test_py_info.py
@@ -291,7 +291,7 @@ def test_discover_exe_on_path_non_spec_name_not_match(mocker):
assert CURRENT.satisfies(spec, impl_must_match=True) is False
-@pytest.mark.skipif(IS_PYPY, reason="setuptools distutil1s patching does not work")
+@pytest.mark.skipif(IS_PYPY, reason="setuptools distutils patching does not work")
def test_py_info_setuptools():
from setuptools.dist import Distribution
diff --git a/tests/unit/discovery/windows/conftest.py b/tests/unit/discovery/windows/conftest.py
index 21ed61b..08c72fd 100644
--- a/tests/unit/discovery/windows/conftest.py
+++ b/tests/unit/discovery/windows/conftest.py
@@ -11,7 +11,7 @@ def _mock_registry(mocker):
from virtualenv.discovery.windows.pep514 import winreg
loc, glob = {}, {}
- mock_value_str = (Path(__file__).parent / "winreg-mock-values.py").read_text()
+ mock_value_str = (Path(__file__).parent / "winreg-mock-values.py").read_text(encoding="utf-8")
exec(mock_value_str, glob, loc)
enum_collect = loc["enum_collect"]
value_collect = loc["value_collect"]
diff --git a/tests/unit/seed/embed/test_base_embed.py b/tests/unit/seed/embed/test_base_embed.py
index e9d61f3..a249e47 100644
--- a/tests/unit/seed/embed/test_base_embed.py
+++ b/tests/unit/seed/embed/test_base_embed.py
@@ -1,5 +1,8 @@
from __future__ import annotations
+import sys
+from pathlib import Path
+
import pytest
from virtualenv.run import session_via_cli
@@ -12,3 +15,13 @@ from virtualenv.run import session_via_cli
def test_download_cli_flag(args, download, tmp_path):
session = session_via_cli(args + [str(tmp_path)])
assert session.seeder.download is download
+
+
+def test_embed_wheel_versions(tmp_path: Path) -> None:
+ session = session_via_cli([str(tmp_path)])
+ expected = (
+ {"pip": "bundle"}
+ if sys.version_info[:2] >= (3, 12)
+ else {"pip": "bundle", "setuptools": "bundle", "wheel": "bundle"}
+ )
+ assert session.seeder.distribution_to_versions() == expected
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 610aaa2..fac9ac6 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
@@ -3,11 +3,13 @@ from __future__ import annotations
import contextlib
import os
import sys
+from pathlib import Path
from stat import S_IWGRP, S_IWOTH, S_IWUSR
from subprocess import Popen, check_call
from threading import Thread
import pytest
+from pytest_mock import MockerFixture
from virtualenv.discovery import cached_py_info
from virtualenv.discovery.py_info import PythonInfo
@@ -202,7 +204,7 @@ def test_populated_read_only_cache_and_copied_app_data(tmp_path, current_fastest
@pytest.mark.parametrize("pkg", ["pip", "setuptools", "wheel"])
@pytest.mark.usefixtures("session_app_data", "current_fastest", "coverage_env")
def test_base_bootstrap_link_via_app_data_no(tmp_path, pkg):
- create_cmd = [str(tmp_path), "--seeder", "app-data", f"--no-{pkg}"]
+ create_cmd = [str(tmp_path), "--seeder", "app-data", f"--no-{pkg}", "--wheel", "bundle", "--setuptools", "bundle"]
result = cli_run(create_cmd)
assert not (result.creator.purelib / pkg).exists()
for key in {"pip", "setuptools", "wheel"} - {pkg}:
@@ -216,7 +218,7 @@ def test_app_data_parallel_ok(tmp_path):
@pytest.mark.usefixtures("temp_app_data")
-def test_app_data_parallel_fail(tmp_path, mocker):
+def test_app_data_parallel_fail(tmp_path: Path, mocker: MockerFixture) -> None:
mocker.patch("virtualenv.seed.embed.via_app_data.pip_install.base.PipInstall.build_image", side_effect=RuntimeError)
exceptions = _run_parallel_threads(tmp_path)
assert len(exceptions) == 2
@@ -230,7 +232,7 @@ def _run_parallel_threads(tmp_path):
def _run(name):
try:
- cli_run(["--seeder", "app-data", str(tmp_path / name), "--no-pip", "--no-setuptools"])
+ cli_run(["--seeder", "app-data", str(tmp_path / name), "--no-pip", "--no-setuptools", "--wheel", "bundle"])
except Exception as exception:
as_str = str(exception)
exceptions.append(as_str)
diff --git a/tests/unit/seed/wheels/test_acquire.py b/tests/unit/seed/wheels/test_acquire.py
index 7f88f6a..dc471a1 100644
--- a/tests/unit/seed/wheels/test_acquire.py
+++ b/tests/unit/seed/wheels/test_acquire.py
@@ -5,8 +5,11 @@ import sys
from datetime import datetime
from pathlib import Path
from subprocess import CalledProcessError
+from typing import Callable
+from unittest.mock import MagicMock
import pytest
+from pytest_mock import MockerFixture
from virtualenv.app_data import AppDataDiskFolder
from virtualenv.seed.wheels.acquire import download_wheel, get_wheel, pip_wheel_env_run
@@ -113,8 +116,14 @@ def test_get_wheel_download_not_called(mocker, for_py_version, session_app_data,
assert write.call_count == 0
-@pytest.mark.usefixtures("freezer")
-def test_get_wheel_download_cached(tmp_path, mocker, for_py_version, downloaded_wheel):
+def test_get_wheel_download_cached(
+ tmp_path: Path,
+ mocker: MockerFixture,
+ for_py_version: str,
+ downloaded_wheel: tuple[Wheel, MagicMock],
+ time_freeze: Callable[[datetime], None],
+) -> None:
+ time_freeze(datetime.now())
from virtualenv.app_data.via_disk_folder import JSONStoreDisk
app_data = AppDataDiskFolder(folder=str(tmp_path))
diff --git a/tests/unit/seed/wheels/test_periodic_update.py b/tests/unit/seed/wheels/test_periodic_update.py
index 82c86e3..d4a5e09 100644
--- a/tests/unit/seed/wheels/test_periodic_update.py
+++ b/tests/unit/seed/wheels/test_periodic_update.py
@@ -68,7 +68,7 @@ def test_manual_upgrade(session_app_data, caplog, mocker, for_py_version):
@pytest.mark.usefixtures("session_app_data")
def test_pick_periodic_update(tmp_path, mocker, for_py_version):
- embed, current = get_embed_wheel("setuptools", "3.5"), get_embed_wheel("setuptools", for_py_version)
+ embed, current = get_embed_wheel("setuptools", "3.6"), get_embed_wheel("setuptools", for_py_version)
mocker.patch("virtualenv.seed.wheels.bundle.load_embed_wheel", return_value=embed)
completed = datetime.now() - timedelta(days=29)
u_log = UpdateLog(
@@ -79,7 +79,20 @@ def test_pick_periodic_update(tmp_path, mocker, for_py_version):
)
read_dict = mocker.patch("virtualenv.app_data.via_disk_folder.JSONStoreDisk.read", return_value=u_log.to_dict())
- result = cli_run([str(tmp_path), "--activators", "", "--no-periodic-update", "--no-wheel", "--no-pip"])
+ result = cli_run(
+ [
+ str(tmp_path),
+ "--activators",
+ "",
+ "--no-periodic-update",
+ "--no-wheel",
+ "--no-pip",
+ "--setuptools",
+ "bundle",
+ "--wheel",
+ "bundle",
+ ],
+ )
assert read_dict.call_count == 1
installed = [i.name for i in result.creator.purelib.iterdir() if i.suffix == ".dist-info"]
@@ -208,8 +221,8 @@ _UPDATE_SKIP = {
@pytest.mark.parametrize("u_log", list(_UPDATE_SKIP.values()), ids=list(_UPDATE_SKIP.keys()))
-def test_periodic_update_skip(u_log, mocker, for_py_version, session_app_data, freezer):
- freezer.move_to(_UP_NOW)
+def test_periodic_update_skip(u_log, mocker, for_py_version, session_app_data, time_freeze):
+ time_freeze(_UP_NOW)
mocker.patch("virtualenv.app_data.via_disk_folder.JSONStoreDisk.read", return_value=u_log.to_dict())
mocker.patch("virtualenv.seed.wheels.periodic_update.trigger_update", side_effect=RuntimeError)
@@ -235,8 +248,8 @@ _UPDATE_YES = {
@pytest.mark.parametrize("u_log", list(_UPDATE_YES.values()), ids=list(_UPDATE_YES.keys()))
-def test_periodic_update_trigger(u_log, mocker, for_py_version, session_app_data, freezer):
- freezer.move_to(_UP_NOW)
+def test_periodic_update_trigger(u_log, mocker, for_py_version, session_app_data, time_freeze):
+ time_freeze(_UP_NOW)
mocker.patch("virtualenv.app_data.via_disk_folder.JSONStoreDisk.read", return_value=u_log.to_dict())
write = mocker.patch("virtualenv.app_data.via_disk_folder.JSONStoreDisk.write")
trigger_update_ = mocker.patch("virtualenv.seed.wheels.periodic_update.trigger_update")
@@ -343,8 +356,8 @@ def test_trigger_update_debug(for_py_version, session_app_data, tmp_path, mocker
assert process.communicate.call_count == 1
-def test_do_update_first(tmp_path, mocker, freezer):
- freezer.move_to(_UP_NOW)
+def test_do_update_first(tmp_path, mocker, time_freeze):
+ time_freeze(_UP_NOW)
wheel = get_embed_wheel("pip", "3.9")
app_data_outer = AppDataDiskFolder(str(tmp_path / "app"))
extra = tmp_path / "extra"
@@ -421,8 +434,8 @@ def test_do_update_first(tmp_path, mocker, freezer):
}
-def test_do_update_skip_already_done(tmp_path, mocker, freezer):
- freezer.move_to(_UP_NOW + timedelta(hours=1))
+def test_do_update_skip_already_done(tmp_path, mocker, time_freeze):
+ time_freeze(_UP_NOW + timedelta(hours=1))
wheel = get_embed_wheel("pip", "3.9")
app_data_outer = AppDataDiskFolder(str(tmp_path / "app"))
extra = tmp_path / "extra"
@@ -535,8 +548,8 @@ def mock_download(mocker, pip_version_remote):
)
-def test_download_stop_with_embed(tmp_path, mocker, freezer):
- freezer.move_to(_UP_NOW)
+def test_download_stop_with_embed(tmp_path, mocker, time_freeze):
+ time_freeze(_UP_NOW)
wheel = get_embed_wheel("pip", "3.9")
app_data_outer = AppDataDiskFolder(str(tmp_path / "app"))
pip_version_remote = [wheel_path(wheel, (0, 0, 2)), wheel_path(wheel, (0, 0, 1)), wheel_path(wheel, (-1, 0, 0))]
@@ -558,8 +571,8 @@ def test_download_stop_with_embed(tmp_path, mocker, freezer):
assert write.call_count == 1
-def test_download_manual_stop_after_one_download(tmp_path, mocker, freezer):
- freezer.move_to(_UP_NOW)
+def test_download_manual_stop_after_one_download(tmp_path, mocker, time_freeze):
+ time_freeze(_UP_NOW)
wheel = get_embed_wheel("pip", "3.9")
app_data_outer = AppDataDiskFolder(str(tmp_path / "app"))
pip_version_remote = [wheel_path(wheel, (0, 1, 1))]
@@ -580,8 +593,8 @@ def test_download_manual_stop_after_one_download(tmp_path, mocker, freezer):
assert write.call_count == 1
-def test_download_manual_ignores_pre_release(tmp_path, mocker, freezer):
- freezer.move_to(_UP_NOW)
+def test_download_manual_ignores_pre_release(tmp_path, mocker, time_freeze):
+ time_freeze(_UP_NOW)
wheel = get_embed_wheel("pip", "3.9")
app_data_outer = AppDataDiskFolder(str(tmp_path / "app"))
pip_version_remote = [wheel_path(wheel, (0, 0, 1))]
@@ -613,8 +626,8 @@ def test_download_manual_ignores_pre_release(tmp_path, mocker, freezer):
]
-def test_download_periodic_stop_at_first_usable(tmp_path, mocker, freezer):
- freezer.move_to(_UP_NOW)
+def test_download_periodic_stop_at_first_usable(tmp_path, mocker, time_freeze):
+ time_freeze(_UP_NOW)
wheel = get_embed_wheel("pip", "3.9")
app_data_outer = AppDataDiskFolder(str(tmp_path / "app"))
pip_version_remote = [wheel_path(wheel, (0, 1, 1)), wheel_path(wheel, (0, 1, 0))]
@@ -641,8 +654,8 @@ def test_download_periodic_stop_at_first_usable(tmp_path, mocker, freezer):
assert write.call_count == 1
-def test_download_periodic_stop_at_first_usable_with_previous_minor(tmp_path, mocker, freezer):
- freezer.move_to(_UP_NOW)
+def test_download_periodic_stop_at_first_usable_with_previous_minor(tmp_path, mocker, time_freeze):
+ time_freeze(_UP_NOW)
wheel = get_embed_wheel("pip", "3.9")
app_data_outer = AppDataDiskFolder(str(tmp_path / "app"))
pip_version_remote = [wheel_path(wheel, (0, 1, 1)), wheel_path(wheel, (0, 1, 0)), wheel_path(wheel, (0, -1, 0))]