--- Begin Message ---
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: python-virtual...@packages.debian.org
Control: affects -1 + src:python-virtualenv
User: release.debian....@packages.debian.org
Usertags: unblock
Please unblock package python-virtualenv
Sorry, I hadn't realized virtualenv was a key package.
[ Reason ]
This version includes the final upstream result of forwarding our
no-wheel-whl patch. My initial approach (strong deprecation) caused some
regressions in other people's CI, so it got watered down.
[ Impact ]
The previous version of virtualenv had a Debian patch that removed the
--wheel and --no-wheel options. These are now silently ignored upstream,
which will cause less downstream breakage.
Being closer to upstream risks less confusion for our users.
[ Tests ]
Third parties have stopped complaining, so I think the current upstream
versions of virtualenv are behaving as they expect.
We have build time and autopkgtests.
[ Risks ]
(Discussion of the risks involved. E.g. code is trivial or
complex, key package vs leaf package, alternatives available.)
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
unblock python-virtualenv/20.31.2+ds-1
diff -Nru python-virtualenv-20.30.0+ds/debian/changelog
python-virtualenv-20.31.2+ds/debian/changelog
--- python-virtualenv-20.30.0+ds/debian/changelog 2025-04-28
19:56:37.000000000 +0200
+++ python-virtualenv-20.31.2+ds/debian/changelog 2025-05-09
15:08:14.000000000 +0200
@@ -1,3 +1,15 @@
+python-virtualenv (20.31.2+ds-1) unstable; urgency=medium
+
+ [ Stefano Rivera ]
+ * New upstream release.
+ * Refresh patches.
+ * Drop no-wheel-whl patch, superseded upstream.
+
+ [ Alexandre Detiste ]
+ * Drop build-dep on python3-importlib-metadata
+
+ -- Stefano Rivera <stefa...@debian.org> Fri, 09 May 2025 09:08:14 -0400
+
python-virtualenv (20.30.0+ds-3) unstable; urgency=medium
* Update no-wheel-whl patch to include a deprecated noop --no-wheel option.
diff -Nru python-virtualenv-20.30.0+ds/debian/control
python-virtualenv-20.31.2+ds/debian/control
--- python-virtualenv-20.30.0+ds/debian/control 2025-04-28 19:56:37.000000000
+0200
+++ python-virtualenv-20.31.2+ds/debian/control 2025-05-09 15:08:14.000000000
+0200
@@ -15,7 +15,6 @@
zip <!nocheck>,
Build-Depends-Indep: python3-distlib (>= 0.3.1) <!nocheck>,
python3-filelock <!nocheck>,
- python3-importlib-metadata (>= 3.6) <!nocheck>,
python3-pip-whl <!nocheck>,
python3-platformdirs <!nocheck>,
python3-hatchling (>= 1.11.1),
diff -Nru
python-virtualenv-20.30.0+ds/debian/patches/debian_update_for_available_wheels.patch
python-virtualenv-20.31.2+ds/debian/patches/debian_update_for_available_wheels.patch
---
python-virtualenv-20.30.0+ds/debian/patches/debian_update_for_available_wheels.patch
2025-04-28 19:56:37.000000000 +0200
+++
python-virtualenv-20.31.2+ds/debian/patches/debian_update_for_available_wheels.patch
2025-05-09 15:08:14.000000000 +0200
@@ -13,10 +13,10 @@
1 file changed, 21 insertions(+)
diff --git a/src/virtualenv/seed/wheels/embed/__init__.py
b/src/virtualenv/seed/wheels/embed/__init__.py
-index 6c50bda..55362c7 100644
+index 5ca63de..6c8180d 100644
--- a/src/virtualenv/seed/wheels/embed/__init__.py
+++ b/src/virtualenv/seed/wheels/embed/__init__.py
-@@ -45,6 +45,27 @@ BUNDLE_SUPPORT = {
+@@ -39,6 +39,27 @@ BUNDLE_SUPPORT = {
MAX = "3.8"
@@ -42,5 +42,5 @@
+
+
def get_embed_wheel(distribution, for_py_version):
- path = BUNDLE_FOLDER / (BUNDLE_SUPPORT.get(for_py_version, {}) or
BUNDLE_SUPPORT[MAX]).get(distribution)
- return Wheel.from_path(path)
+ mapping = BUNDLE_SUPPORT.get(for_py_version, {}) or BUNDLE_SUPPORT[MAX]
+ wheel_file = mapping.get(distribution)
diff -Nru
python-virtualenv-20.30.0+ds/debian/patches/debian_wheel_location.patch
python-virtualenv-20.31.2+ds/debian/patches/debian_wheel_location.patch
--- python-virtualenv-20.30.0+ds/debian/patches/debian_wheel_location.patch
2025-04-28 19:56:37.000000000 +0200
+++ python-virtualenv-20.31.2+ds/debian/patches/debian_wheel_location.patch
2025-05-09 15:08:14.000000000 +0200
@@ -13,7 +13,7 @@
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/virtualenv/seed/wheels/embed/__init__.py
b/src/virtualenv/seed/wheels/embed/__init__.py
-index 4727e61..6c50bda 100644
+index 6b3ef26..5ca63de 100644
--- a/src/virtualenv/seed/wheels/embed/__init__.py
+++ b/src/virtualenv/seed/wheels/embed/__init__.py
@@ -4,7 +4,7 @@ from pathlib import Path
diff -Nru
python-virtualenv-20.30.0+ds/debian/patches/disable-periodic-update.patch
python-virtualenv-20.31.2+ds/debian/patches/disable-periodic-update.patch
--- python-virtualenv-20.30.0+ds/debian/patches/disable-periodic-update.patch
2025-04-28 19:56:37.000000000 +0200
+++ python-virtualenv-20.31.2+ds/debian/patches/disable-periodic-update.patch
2025-05-09 15:08:14.000000000 +0200
@@ -11,13 +11,13 @@
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/virtualenv/seed/embed/base_embed.py
b/src/virtualenv/seed/embed/base_embed.py
-index 864cc49..7d83cb6 100644
+index 72fc5a3..59f3f2c 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
+@@ -9,7 +9,7 @@ from virtualenv.seed.seeder import Seeder
from virtualenv.seed.wheels import Version
+ LOGGER = logging.getLogger(__name__)
-PERIODIC_UPDATE_ON_BY_DEFAULT = True
+PERIODIC_UPDATE_ON_BY_DEFAULT = False
diff -Nru python-virtualenv-20.30.0+ds/debian/patches/no-wheel-whl
python-virtualenv-20.31.2+ds/debian/patches/no-wheel-whl
--- python-virtualenv-20.30.0+ds/debian/patches/no-wheel-whl 2025-04-28
19:56:37.000000000 +0200
+++ python-virtualenv-20.31.2+ds/debian/patches/no-wheel-whl 1970-01-01
01:00:00.000000000 +0100
@@ -1,324 +0,0 @@
-From: Stefano Rivera <stef...@rivera.za.net>
-Date: Thu, 10 Apr 2025 17:40:16 -0400
-Subject: Stop including 'wheel',
- setuptools 70.1 has native bdist_wheel support
-
-Forwarded: https://github.com/pypa/virtualenv/pull/2868
-Bug-Upstream: https://github.com/pypa/virtualenv/issues/2873
----
- src/virtualenv/seed/embed/base_embed.py | 23 ++++++++++++++++++----
- src/virtualenv/seed/wheels/embed/__init__.py | 7 -------
- tests/unit/config/test___main__.py | 4 ++--
- tests/unit/create/test_creator.py | 4 +---
- tests/unit/seed/embed/test_base_embed.py | 21 +++++++++++++++-----
- .../seed/embed/test_bootstrap_link_via_app_data.py | 12 +++++------
- tests/unit/seed/embed/test_pip_invoke.py | 7 +++----
- tests/unit/seed/wheels/test_periodic_update.py | 5 +----
- 8 files changed, 48 insertions(+), 35 deletions(-)
-
-diff --git a/src/virtualenv/seed/embed/base_embed.py
b/src/virtualenv/seed/embed/base_embed.py
-index 7d83cb6..94e5ed4 100644
---- a/src/virtualenv/seed/embed/base_embed.py
-+++ b/src/virtualenv/seed/embed/base_embed.py
-@@ -1,7 +1,9 @@
- from __future__ import annotations
-
- from abc import ABC
-+from argparse import SUPPRESS
- from pathlib import Path
-+from warnings import warn
-
- from virtualenv.seed.seeder import Seeder
- from virtualenv.seed.wheels import Version
-@@ -18,14 +20,21 @@ class BaseEmbed(Seeder, ABC):
-
- self.pip_version = options.pip
- self.setuptools_version = options.setuptools
-- self.wheel_version = options.wheel
-
- self.no_pip = options.no_pip
- self.no_setuptools = options.no_setuptools
-- self.no_wheel = options.no_wheel
- self.app_data = options.app_data
- self.periodic_update = not options.no_periodic_update
-
-+ if options.no_wheel:
-+ warn(
-+ "The --no-wheel option is deprecated. "
-+ "It has no effect, wheel is no longer bundled in virtualenv. "
-+ "This option will be removed in pip 26.",
-+ DeprecationWarning,
-+ stacklevel=1,
-+ )
-+
- if not self.distribution_to_versions():
- self.enabled = False
-
-@@ -34,7 +43,6 @@ class BaseEmbed(Seeder, ABC):
- return {
- "pip": Version.bundle,
- "setuptools": Version.bundle,
-- "wheel": Version.bundle,
- }
-
- def distribution_to_versions(self) -> dict[str, str]:
-@@ -71,7 +79,7 @@ class BaseEmbed(Seeder, ABC):
- default=[],
- )
- for distribution, default in cls.distributions().items():
-- if interpreter.version_info[:2] >= (3, 12) and distribution in
{"wheel", "setuptools"}:
-+ if interpreter.version_info[:2] >= (3, 12) and distribution ==
"setuptools":
- default = "none" # noqa: PLW2901
- parser.add_argument(
- f"--{distribution}",
-@@ -88,6 +96,13 @@ class BaseEmbed(Seeder, ABC):
- help=f"do not install {distribution}",
- default=False,
- )
-+ # DEPRECATED: Remove in pip 26
-+ parser.add_argument(
-+ "--no-wheel",
-+ dest="no_wheel",
-+ action="store_true",
-+ help=SUPPRESS,
-+ )
- parser.add_argument(
- "--no-periodic-update",
- dest="no_periodic_update",
-diff --git a/src/virtualenv/seed/wheels/embed/__init__.py
b/src/virtualenv/seed/wheels/embed/__init__.py
-index adc9216..2426081 100644
---- a/src/virtualenv/seed/wheels/embed/__init__.py
-+++ b/src/virtualenv/seed/wheels/embed/__init__.py
-@@ -9,37 +9,30 @@ BUNDLE_SUPPORT = {
- "3.8": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-75.3.2-py3-none-any.whl",
-- "wheel": "wheel-0.45.1-py3-none-any.whl",
- },
- "3.9": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
-- "wheel": "wheel-0.45.1-py3-none-any.whl",
- },
- "3.10": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
-- "wheel": "wheel-0.45.1-py3-none-any.whl",
- },
- "3.11": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
-- "wheel": "wheel-0.45.1-py3-none-any.whl",
- },
- "3.12": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
-- "wheel": "wheel-0.45.1-py3-none-any.whl",
- },
- "3.13": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
-- "wheel": "wheel-0.45.1-py3-none-any.whl",
- },
- "3.14": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
-- "wheel": "wheel-0.45.1-py3-none-any.whl",
- },
- }
- MAX = "3.8"
-diff --git a/tests/unit/config/test___main__.py
b/tests/unit/config/test___main__.py
-index fc6b3ee..b7c1850 100644
---- a/tests/unit/config/test___main__.py
-+++ b/tests/unit/config/test___main__.py
-@@ -64,7 +64,7 @@ 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: Path, capsys:
pytest.CaptureFixture[str]) -> None:
-- run_with_catch([str(tmp_path), "--setuptools", "bundle", "--wheel",
"bundle"])
-+ run_with_catch([str(tmp_path), "--setuptools", "bundle"])
- out, err = capsys.readouterr()
- assert not err
- lines = out.splitlines()
-@@ -72,7 +72,7 @@ def test_session_report_full(tmp_path: Path, capsys:
pytest.CaptureFixture[str])
- r"created virtual environment .* in \d+ms",
- r" creator .*",
- r" seeder .*",
-- r" added seed packages: .*pip==.*, setuptools==.*, wheel==.*",
-+ r" added seed packages: .*pip==.*, setuptools==.*",
- r" activators .*",
- ]
- _match_regexes(lines, regexes)
-diff --git a/tests/unit/create/test_creator.py
b/tests/unit/create/test_creator.py
-index ed1cb11..2b4b1c0 100644
---- a/tests/unit/create/test_creator.py
-+++ b/tests/unit/create/test_creator.py
-@@ -411,8 +411,6 @@ def test_create_distutils_cfg(creator, tmp_path,
monkeypatch):
- creator,
- "--setuptools",
- "bundle",
-- "--wheel",
-- "bundle",
- ],
- )
-
-@@ -470,7 +468,7 @@ 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", "--setuptools", "bundle"],
-+ [str(tmp_path / "venv"), "--activators", "", "--no-pip", "--copies",
"--setuptools", "bundle"],
- )
- zip_path = tmp_path / "site-packages.zip"
- with zipfile.ZipFile(str(zip_path), "w", zipfile.ZIP_DEFLATED) as
zip_handler:
-diff --git a/tests/unit/seed/embed/test_base_embed.py
b/tests/unit/seed/embed/test_base_embed.py
-index 255e031..73754a5 100644
---- a/tests/unit/seed/embed/test_base_embed.py
-+++ b/tests/unit/seed/embed/test_base_embed.py
-@@ -1,6 +1,7 @@
- from __future__ import annotations
-
- import sys
-+import warnings
- from typing import TYPE_CHECKING
-
- import pytest
-@@ -20,11 +21,21 @@ def test_download_cli_flag(args, download, tmp_path):
- assert session.seeder.download is download
-
-
-+# DEPRECATED: Remove in pip 26
-+def test_download_deprecated_cli_flag(tmp_path):
-+ with warnings.catch_warnings(record=True) as w:
-+ warnings.simplefilter("always")
-+ session_via_cli(["--no-wheel", str(tmp_path)])
-+ assert len(w) == 1
-+ assert issubclass(w[-1].category, DeprecationWarning)
-+ assert str(w[-1].message) == (
-+ "The --no-wheel option is deprecated. "
-+ "It has no effect, wheel is no longer bundled in virtualenv. "
-+ "This option will be removed in pip 26."
-+ )
-+
-+
- 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"}
-- )
-+ expected = {"pip": "bundle"} if sys.version_info[:2] >= (3, 12) else
{"pip": "bundle", "setuptools": "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 2448d90..bfbb424 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
-@@ -110,7 +110,7 @@ def test_seed_link_via_app_data(tmp_path, coverage_env,
current_fastest, copies)
- # Windows does not allow removing a executable while running it, so when
uninstalling pip we need to do it via
- # python -m pip
- remove_cmd = [str(result.creator.exe), "-m", "pip"] + remove_cmd[1:]
-- process = Popen([*remove_cmd, "pip", "wheel"])
-+ process = Popen([*remove_cmd, "pip"])
- _, __ = process.communicate()
- assert not process.returncode
- # pip is greedy here, removing all packages removes the site-package too
-@@ -208,13 +208,13 @@ def
test_populated_read_only_cache_and_copied_app_data(tmp_path, current_fastest
-
-
- @pytest.mark.slow
--@pytest.mark.parametrize("pkg", ["pip", "setuptools", "wheel"])
-+@pytest.mark.parametrize("pkg", ["pip", "setuptools"])
- @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}",
"--wheel", "bundle", "--setuptools", "bundle"]
-+ create_cmd = [str(tmp_path), "--seeder", "app-data", f"--no-{pkg}",
"--setuptools", "bundle"]
- result = cli_run(create_cmd)
- assert not (result.creator.purelib / pkg).exists()
-- for key in {"pip", "setuptools", "wheel"} - {pkg}:
-+ for key in {"pip", "setuptools"} - {pkg}:
- assert (result.creator.purelib / key).exists()
-
-
-@@ -230,7 +230,7 @@ def test_app_data_parallel_fail(tmp_path: Path, mocker:
MockerFixture) -> None:
- exceptions = _run_parallel_threads(tmp_path)
- assert len(exceptions) == 2
- for exception in exceptions:
-- assert exception.startswith("failed to build image wheel
because:\nTraceback")
-+ assert exception.startswith("failed to build image pip
because:\nTraceback")
- assert "RuntimeError" in exception, exception
-
-
-@@ -239,7 +239,7 @@ def _run_parallel_threads(tmp_path):
-
- def _run(name):
- try:
-- cli_run(["--seeder", "app-data", str(tmp_path / name),
"--no-pip", "--no-setuptools", "--wheel", "bundle"])
-+ cli_run(["--seeder", "app-data", str(tmp_path / name),
"--no-setuptools"])
- except Exception as exception: # noqa: BLE001
- as_str = str(exception)
- exceptions.append(as_str)
-diff --git a/tests/unit/seed/embed/test_pip_invoke.py
b/tests/unit/seed/embed/test_pip_invoke.py
-index d8c243e..97d4d33 100644
---- a/tests/unit/seed/embed/test_pip_invoke.py
-+++ b/tests/unit/seed/embed/test_pip_invoke.py
-@@ -13,7 +13,7 @@ from virtualenv.seed.wheels.embed import BUNDLE_FOLDER,
BUNDLE_SUPPORT
-
-
- @pytest.mark.slow
--@pytest.mark.parametrize("no", ["pip", "setuptools", "wheel", ""])
-+@pytest.mark.parametrize("no", ["pip", "setuptools", ""])
- def test_base_bootstrap_via_pip_invoke(tmp_path, coverage_env, mocker,
current_fastest, no): # noqa: C901
- extra_search_dir = tmp_path / "extra"
- extra_search_dir.mkdir()
-@@ -49,7 +49,7 @@ def test_base_bootstrap_via_pip_invoke(tmp_path,
coverage_env, mocker, current_f
-
- original = PipInvoke._execute # noqa: SLF001
- run = mocker.patch.object(PipInvoke, "_execute", side_effect=_execute)
-- versions = {"pip": "embed", "setuptools": "bundle", "wheel":
new["wheel"].split("-")[1]}
-+ versions = {"pip": "embed", "setuptools": "bundle"}
-
- create_cmd = [
- "--seeder",
-@@ -76,14 +76,13 @@ def test_base_bootstrap_via_pip_invoke(tmp_path,
coverage_env, mocker, current_f
- site_package = result.creator.purelib
- pip = site_package / "pip"
- setuptools = site_package / "setuptools"
-- wheel = site_package / "wheel"
- files_post_first_create = list(site_package.iterdir())
-
- if no:
- no_file = locals()[no]
- assert no not in files_post_first_create
-
-- for key in ("pip", "setuptools", "wheel"):
-+ for key in ("pip", "setuptools"):
- if key == no:
- continue
- assert locals()[key] in files_post_first_create
-diff --git a/tests/unit/seed/wheels/test_periodic_update.py
b/tests/unit/seed/wheels/test_periodic_update.py
-index 3b0529a..731252f 100644
---- a/tests/unit/seed/wheels/test_periodic_update.py
-+++ b/tests/unit/seed/wheels/test_periodic_update.py
-@@ -74,7 +74,7 @@ def test_manual_upgrade(session_app_data, caplog, mocker,
for_py_version):
- packages[args[1]["distribution"]].append(args[1]["for_py_version"])
- packages = {key: sorted(value) for key, value in packages.items()}
- versions = sorted(BUNDLE_SUPPORT.keys())
-- expected = {"setuptools": versions, "wheel": versions, "pip": versions}
-+ expected = {"setuptools": versions, "pip": versions}
- assert packages == expected
-
-
-@@ -97,12 +97,9 @@ def test_pick_periodic_update(tmp_path, mocker,
for_py_version):
- "--activators",
- "",
- "--no-periodic-update",
-- "--no-wheel",
- "--no-pip",
- "--setuptools",
- "bundle",
-- "--wheel",
-- "bundle",
- ],
- )
-
diff -Nru python-virtualenv-20.30.0+ds/debian/patches/series
python-virtualenv-20.31.2+ds/debian/patches/series
--- python-virtualenv-20.30.0+ds/debian/patches/series 2025-04-28
19:56:37.000000000 +0200
+++ python-virtualenv-20.31.2+ds/debian/patches/series 2025-05-09
15:08:14.000000000 +0200
@@ -2,4 +2,3 @@
debian_update_for_available_wheels.patch
disable-periodic-update.patch
wheel-package-error
-no-wheel-whl
diff -Nru python-virtualenv-20.30.0+ds/debian/patches/wheel-package-error
python-virtualenv-20.31.2+ds/debian/patches/wheel-package-error
--- python-virtualenv-20.30.0+ds/debian/patches/wheel-package-error
2025-04-28 19:56:37.000000000 +0200
+++ python-virtualenv-20.31.2+ds/debian/patches/wheel-package-error
2025-05-09 15:08:14.000000000 +0200
@@ -4,14 +4,14 @@
Forwarded: not-needed
---
- src/virtualenv/seed/wheels/embed/__init__.py | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
+ src/virtualenv/seed/wheels/embed/__init__.py | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
diff --git a/src/virtualenv/seed/wheels/embed/__init__.py
b/src/virtualenv/seed/wheels/embed/__init__.py
-index 55362c7..adc9216 100644
+index 6c8180d..6ed9727 100644
--- a/src/virtualenv/seed/wheels/embed/__init__.py
+++ b/src/virtualenv/seed/wheels/embed/__init__.py
-@@ -67,6 +67,19 @@ BUNDLE_SUPPORT =
list_available_wheels(BUNDLE_SUPPORT.keys())
+@@ -61,6 +61,20 @@ BUNDLE_SUPPORT =
list_available_wheels(BUNDLE_SUPPORT.keys())
def get_embed_wheel(distribution, for_py_version):
@@ -27,7 +27,8 @@
+ '2' if for_py_version == '2.7' else '3',
+ distribution,
+ ))
++ # End Debian specific
+
- path = BUNDLE_FOLDER / (BUNDLE_SUPPORT.get(for_py_version, {}) or
BUNDLE_SUPPORT[MAX]).get(distribution)
- return Wheel.from_path(path)
-
+ mapping = BUNDLE_SUPPORT.get(for_py_version, {}) or BUNDLE_SUPPORT[MAX]
+ wheel_file = mapping.get(distribution)
+ if wheel_file is None:
diff -Nru python-virtualenv-20.30.0+ds/PKG-INFO
python-virtualenv-20.31.2+ds/PKG-INFO
--- python-virtualenv-20.30.0+ds/PKG-INFO 2020-02-02 01:00:00.000000000
+0100
+++ python-virtualenv-20.31.2+ds/PKG-INFO 2020-02-02 01:00:00.000000000
+0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: virtualenv
-Version: 20.30.0
+Version: 20.31.2
Summary: Virtual Python Environment builder
Project-URL: Documentation, https://virtualenv.pypa.io
Project-URL: Homepage, https://github.com/pypa/virtualenv
diff -Nru python-virtualenv-20.30.0+ds/src/virtualenv/config/cli/parser.py
python-virtualenv-20.31.2+ds/src/virtualenv/config/cli/parser.py
--- python-virtualenv-20.30.0+ds/src/virtualenv/config/cli/parser.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/src/virtualenv/config/cli/parser.py
2020-02-02 01:00:00.000000000 +0100
@@ -107,8 +107,8 @@
class HelpFormatter(ArgumentDefaultsHelpFormatter):
- def __init__(self, prog) -> None:
- super().__init__(prog, max_help_position=32, width=240)
+ def __init__(self, prog, **kwargs) -> None:
+ super().__init__(prog, max_help_position=32, width=240, **kwargs)
def _get_help_string(self, action):
text = super()._get_help_string(action)
diff -Nru python-virtualenv-20.30.0+ds/src/virtualenv/run/__init__.py
python-virtualenv-20.31.2+ds/src/virtualenv/run/__init__.py
--- python-virtualenv-20.30.0+ds/src/virtualenv/run/__init__.py 2020-02-02
01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/src/virtualenv/run/__init__.py 2020-02-02
01:00:00.000000000 +0100
@@ -48,6 +48,7 @@
env = os.environ if env is None else env
parser, elements = build_parser(args, options, setup_logging, env)
options = parser.parse_args(args)
+ options.py_version = parser._interpreter.version_info # noqa: SLF001
creator, seeder, activators = tuple(e.create(options) for e in elements)
# create types
return Session(
options.verbosity,
diff -Nru python-virtualenv-20.30.0+ds/src/virtualenv/seed/embed/base_embed.py
python-virtualenv-20.31.2+ds/src/virtualenv/seed/embed/base_embed.py
--- python-virtualenv-20.30.0+ds/src/virtualenv/seed/embed/base_embed.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/src/virtualenv/seed/embed/base_embed.py
2020-02-02 01:00:00.000000000 +0100
@@ -1,11 +1,14 @@
from __future__ import annotations
+import logging
from abc import ABC
+from argparse import SUPPRESS
from pathlib import Path
from virtualenv.seed.seeder import Seeder
from virtualenv.seed.wheels import Version
+LOGGER = logging.getLogger(__name__)
PERIODIC_UPDATE_ON_BY_DEFAULT = True
@@ -18,7 +21,11 @@
self.pip_version = options.pip
self.setuptools_version = options.setuptools
- self.wheel_version = options.wheel
+
+ # wheel version needs special handling
+ # on Python > 3.8, the default is None (as in not used)
+ # so we can differentiate between explicit and implicit none
+ self.wheel_version = options.wheel or "none"
self.no_pip = options.no_pip
self.no_setuptools = options.no_setuptools
@@ -26,6 +33,15 @@
self.app_data = options.app_data
self.periodic_update = not options.no_periodic_update
+ if options.py_version[:2] >= (3, 9):
+ if options.wheel is not None or options.no_wheel:
+ LOGGER.warning(
+ "The --no-wheel and --wheel options are deprecated. "
+ "They have no effect for Python > 3.8 as wheel is no
longer "
+ "bundled in virtualenv.",
+ )
+ self.no_wheel = True
+
if not self.distribution_to_versions():
self.enabled = False
@@ -41,7 +57,7 @@
return {
distribution: getattr(self, f"{distribution}_version")
for distribution in self.distributions()
- if getattr(self, f"no_{distribution}") is False and getattr(self,
f"{distribution}_version") != "none"
+ if getattr(self, f"no_{distribution}", None) is False and
getattr(self, f"{distribution}_version") != "none"
}
@classmethod
@@ -71,21 +87,28 @@
default=[],
)
for distribution, default in cls.distributions().items():
+ help_ = f"version of {distribution} to install as seed: embed,
bundle, none or exact version"
if interpreter.version_info[:2] >= (3, 12) and distribution in
{"wheel", "setuptools"}:
default = "none" # noqa: PLW2901
+ if interpreter.version_info[:2] >= (3, 9) and distribution ==
"wheel":
+ default = None # noqa: PLW2901
+ help_ = SUPPRESS
parser.add_argument(
f"--{distribution}",
dest=distribution,
metavar="version",
- help=f"version of {distribution} to install as seed: embed,
bundle, none or exact version",
+ help=help_,
default=default,
)
for distribution in cls.distributions():
+ help_ = f"do not install {distribution}"
+ if interpreter.version_info[:2] >= (3, 9) and distribution ==
"wheel":
+ help_ = SUPPRESS
parser.add_argument(
f"--no-{distribution}",
dest=f"no_{distribution}",
action="store_true",
- help=f"do not install {distribution}",
+ help=help_,
default=False,
)
parser.add_argument(
@@ -103,7 +126,7 @@
result += f"extra_search_dir={', '.join(str(i) for i in
self.extra_search_dir)},"
result += f"download={self.download},"
for distribution in self.distributions():
- if getattr(self, f"no_{distribution}"):
+ if getattr(self, f"no_{distribution}", None):
continue
version = getattr(self, f"{distribution}_version", None)
if version == "none":
diff -Nru
python-virtualenv-20.30.0+ds/src/virtualenv/seed/wheels/embed/__init__.py
python-virtualenv-20.31.2+ds/src/virtualenv/seed/wheels/embed/__init__.py
--- python-virtualenv-20.30.0+ds/src/virtualenv/seed/wheels/embed/__init__.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/src/virtualenv/seed/wheels/embed/__init__.py
2020-02-02 01:00:00.000000000 +0100
@@ -12,41 +12,39 @@
"wheel": "wheel-0.45.1-py3-none-any.whl",
},
"3.9": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
- "wheel": "wheel-0.45.1-py3-none-any.whl",
+ "pip": "pip-25.1.1-py3-none-any.whl",
+ "setuptools": "setuptools-80.3.1-py3-none-any.whl",
},
"3.10": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
- "wheel": "wheel-0.45.1-py3-none-any.whl",
+ "pip": "pip-25.1.1-py3-none-any.whl",
+ "setuptools": "setuptools-80.3.1-py3-none-any.whl",
},
"3.11": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
- "wheel": "wheel-0.45.1-py3-none-any.whl",
+ "pip": "pip-25.1.1-py3-none-any.whl",
+ "setuptools": "setuptools-80.3.1-py3-none-any.whl",
},
"3.12": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
- "wheel": "wheel-0.45.1-py3-none-any.whl",
+ "pip": "pip-25.1.1-py3-none-any.whl",
+ "setuptools": "setuptools-80.3.1-py3-none-any.whl",
},
"3.13": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
- "wheel": "wheel-0.45.1-py3-none-any.whl",
+ "pip": "pip-25.1.1-py3-none-any.whl",
+ "setuptools": "setuptools-80.3.1-py3-none-any.whl",
},
"3.14": {
- "pip": "pip-25.0.1-py3-none-any.whl",
- "setuptools": "setuptools-78.1.0-py3-none-any.whl",
- "wheel": "wheel-0.45.1-py3-none-any.whl",
+ "pip": "pip-25.1.1-py3-none-any.whl",
+ "setuptools": "setuptools-80.3.1-py3-none-any.whl",
},
}
MAX = "3.8"
def get_embed_wheel(distribution, for_py_version):
- path = BUNDLE_FOLDER / (BUNDLE_SUPPORT.get(for_py_version, {}) or
BUNDLE_SUPPORT[MAX]).get(distribution)
+ mapping = BUNDLE_SUPPORT.get(for_py_version, {}) or BUNDLE_SUPPORT[MAX]
+ wheel_file = mapping.get(distribution)
+ if wheel_file is None:
+ return None
+ path = BUNDLE_FOLDER / wheel_file
return Wheel.from_path(path)
diff -Nru python-virtualenv-20.30.0+ds/src/virtualenv/version.py
python-virtualenv-20.31.2+ds/src/virtualenv/version.py
--- python-virtualenv-20.30.0+ds/src/virtualenv/version.py 2020-02-02
01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/src/virtualenv/version.py 2020-02-02
01:00:00.000000000 +0100
@@ -17,5 +17,5 @@
__version_tuple__: VERSION_TUPLE
version_tuple: VERSION_TUPLE
-__version__ = version = '20.30.0'
-__version_tuple__ = version_tuple = (20, 30, 0)
+__version__ = version = '20.31.2'
+__version_tuple__ = version_tuple = (20, 31, 2)
diff -Nru python-virtualenv-20.30.0+ds/tasks/upgrade_wheels.py
python-virtualenv-20.31.2+ds/tasks/upgrade_wheels.py
--- python-virtualenv-20.30.0+ds/tasks/upgrade_wheels.py 2020-02-02
01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/tasks/upgrade_wheels.py 2020-02-02
01:00:00.000000000 +0100
@@ -38,7 +38,7 @@
)
-def run(): # noqa: C901
+def run(): # noqa: C901, PLR0912
old_batch = {i.name for i in DEST.iterdir() if i.suffix == ".whl"}
with TemporaryDirectory() as temp:
temp_path = Path(temp)
@@ -50,6 +50,8 @@
into.mkdir()
folders[into] = support_ver
for package in BUNDLED:
+ if package == "wheel" and support >= (3, 9):
+ continue
thread = Thread(target=download, args=(support_ver, str(into),
package))
targets.append(thread)
thread.start()
@@ -90,8 +92,10 @@
if (folder / package).exists():
support_table[version].append(package)
support_table = {k: OrderedDict((i.split("-")[0], i) for i in v) for
k, v in support_table.items()}
- bundle = ",".join(
- f"{v!r}: {{ {','.join(f'{p!r}: {f!r}' for p, f in line.items())}
}}" for v, line in support_table.items()
+ nl = "\n"
+ bundle = "".join(
+ f"\n {v!r}: {{{nl}{''.join(f' {p!r}: {f!r},{nl}'
for p, f in line.items())} }},"
+ for v, line in support_table.items()
)
msg = dedent(
f"""
diff -Nru python-virtualenv-20.30.0+ds/tests/unit/config/test___main__.py
python-virtualenv-20.31.2+ds/tests/unit/config/test___main__.py
--- python-virtualenv-20.30.0+ds/tests/unit/config/test___main__.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/tests/unit/config/test___main__.py
2020-02-02 01:00:00.000000000 +0100
@@ -64,7 +64,7 @@
@pytest.mark.usefixtures("session_app_data")
def test_session_report_full(tmp_path: Path, capsys:
pytest.CaptureFixture[str]) -> None:
- run_with_catch([str(tmp_path), "--setuptools", "bundle", "--wheel",
"bundle"])
+ run_with_catch([str(tmp_path), "--setuptools", "bundle"])
out, err = capsys.readouterr()
assert not err
lines = out.splitlines()
@@ -72,7 +72,7 @@
r"created virtual environment .* in \d+ms",
r" creator .*",
r" seeder .*",
- r" added seed packages: .*pip==.*, setuptools==.*, wheel==.*",
+ r" added seed packages: .*pip==.*, setuptools==.*",
r" activators .*",
]
_match_regexes(lines, regexes)
diff -Nru python-virtualenv-20.30.0+ds/tests/unit/create/test_creator.py
python-virtualenv-20.31.2+ds/tests/unit/create/test_creator.py
--- python-virtualenv-20.30.0+ds/tests/unit/create/test_creator.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/tests/unit/create/test_creator.py
2020-02-02 01:00:00.000000000 +0100
@@ -411,8 +411,6 @@
creator,
"--setuptools",
"bundle",
- "--wheel",
- "bundle",
],
)
diff -Nru python-virtualenv-20.30.0+ds/tests/unit/seed/embed/test_base_embed.py
python-virtualenv-20.31.2+ds/tests/unit/seed/embed/test_base_embed.py
--- python-virtualenv-20.30.0+ds/tests/unit/seed/embed/test_base_embed.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/tests/unit/seed/embed/test_base_embed.py
2020-02-02 01:00:00.000000000 +0100
@@ -20,11 +20,46 @@
assert session.seeder.download is download
+@pytest.mark.skipif(sys.version_info[:2] == (3, 8), reason="We still bundle
wheel for Python 3.8")
+@pytest.mark.parametrize("flag", ["--no-wheel", "--wheel=none",
"--wheel=embed", "--wheel=bundle"])
+def test_wheel_cli_flags_do_nothing(tmp_path, flag):
+ session = session_via_cli([flag, str(tmp_path)])
+ if sys.version_info[:2] >= (3, 12):
+ expected = {"pip": "bundle"}
+ else:
+ expected = {"pip": "bundle", "setuptools": "bundle"}
+ assert session.seeder.distribution_to_versions() == expected
+
+
+@pytest.mark.skipif(sys.version_info[:2] == (3, 8), reason="We still bundle
wheel for Python 3.8")
+@pytest.mark.parametrize("flag", ["--no-wheel", "--wheel=none",
"--wheel=embed", "--wheel=bundle"])
+def test_wheel_cli_flags_warn(tmp_path, flag, capsys):
+ session_via_cli([flag, str(tmp_path)])
+ out, err = capsys.readouterr()
+ assert "The --no-wheel and --wheel options are deprecated." in out + err
+
+
+@pytest.mark.skipif(sys.version_info[:2] == (3, 8), reason="We still bundle
wheel for Python 3.8")
+def test_unused_wheel_cli_flags_dont_warn(tmp_path, capsys):
+ session_via_cli([str(tmp_path)])
+ out, err = capsys.readouterr()
+ assert "The --no-wheel and --wheel options are deprecated." not in out +
err
+
+
+@pytest.mark.skipif(sys.version_info[:2] != (3, 8), reason="We only bundle
wheel for Python 3.8")
+@pytest.mark.parametrize("flag", ["--no-wheel", "--wheel=none",
"--wheel=embed", "--wheel=bundle"])
+def test_wheel_cli_flags_dont_warn_on_38(tmp_path, flag, capsys):
+ session_via_cli([flag, str(tmp_path)])
+ out, err = capsys.readouterr()
+ assert "The --no-wheel and --wheel options are deprecated." not in out +
err
+
+
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"}
- )
+ if sys.version_info[:2] >= (3, 12):
+ expected = {"pip": "bundle"}
+ elif sys.version_info[:2] >= (3, 9):
+ expected = {"pip": "bundle", "setuptools": "bundle"}
+ else:
+ expected = {"pip": "bundle", "setuptools": "bundle", "wheel": "bundle"}
assert session.seeder.distribution_to_versions() == expected
diff -Nru
python-virtualenv-20.30.0+ds/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
python-virtualenv-20.31.2+ds/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
---
python-virtualenv-20.30.0+ds/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
2020-02-02 01:00:00.000000000 +0100
+++
python-virtualenv-20.31.2+ds/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
2020-02-02 01:00:00.000000000 +0100
@@ -25,7 +25,7 @@
@pytest.mark.slow
@pytest.mark.parametrize("copies", [False, True] if fs_supports_symlink() else
[True])
-def test_seed_link_via_app_data(tmp_path, coverage_env, current_fastest,
copies):
+def test_seed_link_via_app_data(tmp_path, coverage_env, current_fastest,
copies, for_py_version): # noqa: PLR0915
current = PythonInfo.current_system()
bundle_ver = BUNDLE_SUPPORT[current.version_release_str]
create_cmd = [
@@ -45,6 +45,8 @@
current_fastest,
"-vv",
]
+ if for_py_version == "3.8":
+ create_cmd += ["--wheel", bundle_ver["wheel"].split("-")[1]]
if not copies:
create_cmd.append("--symlink-app-data")
result = cli_run(create_cmd)
@@ -109,7 +111,7 @@
# Windows does not allow removing a executable while running it, so when
uninstalling pip we need to do it via
# python -m pip
- remove_cmd = [str(result.creator.exe), "-m", "pip"] + remove_cmd[1:]
+ remove_cmd = [str(result.creator.exe), "-m", "pip", *remove_cmd[1:]]
process = Popen([*remove_cmd, "pip", "wheel"])
_, __ = process.communicate()
assert not process.returncode
@@ -210,11 +212,18 @@
@pytest.mark.slow
@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}",
"--wheel", "bundle", "--setuptools", "bundle"]
+def test_base_bootstrap_link_via_app_data_no(tmp_path, pkg, for_py_version):
+ if for_py_version != "3.8" and pkg == "wheel":
+ msg = "wheel isn't installed on Python > 3.8"
+ raise pytest.skip(msg)
+ create_cmd = [str(tmp_path), "--seeder", "app-data", f"--no-{pkg}",
"--setuptools", "bundle"]
+ if for_py_version == "3.8":
+ create_cmd += ["--wheel", "bundle"]
result = cli_run(create_cmd)
assert not (result.creator.purelib / pkg).exists()
for key in {"pip", "setuptools", "wheel"} - {pkg}:
+ if for_py_version != "3.8" and key == "wheel":
+ continue
assert (result.creator.purelib / key).exists()
@@ -230,7 +239,7 @@
exceptions = _run_parallel_threads(tmp_path)
assert len(exceptions) == 2
for exception in exceptions:
- assert exception.startswith("failed to build image wheel
because:\nTraceback")
+ assert exception.startswith("failed to build image pip
because:\nTraceback")
assert "RuntimeError" in exception, exception
@@ -239,7 +248,10 @@
def _run(name):
try:
- cli_run(["--seeder", "app-data", str(tmp_path / name), "--no-pip",
"--no-setuptools", "--wheel", "bundle"])
+ cmd = ["--seeder", "app-data", str(tmp_path / name),
"--no-setuptools"]
+ if sys.version_info[:2] == (3, 8):
+ cmd.append("--no-wheel")
+ cli_run(cmd)
except Exception as exception: # noqa: BLE001
as_str = str(exception)
exceptions.append(as_str)
diff -Nru python-virtualenv-20.30.0+ds/tests/unit/seed/embed/test_pip_invoke.py
python-virtualenv-20.31.2+ds/tests/unit/seed/embed/test_pip_invoke.py
--- python-virtualenv-20.30.0+ds/tests/unit/seed/embed/test_pip_invoke.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/tests/unit/seed/embed/test_pip_invoke.py
2020-02-02 01:00:00.000000000 +0100
@@ -49,7 +49,9 @@
original = PipInvoke._execute # noqa: SLF001
run = mocker.patch.object(PipInvoke, "_execute", side_effect=_execute)
- versions = {"pip": "embed", "setuptools": "bundle", "wheel":
new["wheel"].split("-")[1]}
+ versions = {"pip": "embed", "setuptools": "bundle"}
+ if sys.version_info[:2] == (3, 8):
+ versions["wheel"] = new["wheel"].split("-")[1]
create_cmd = [
"--seeder",
@@ -86,4 +88,6 @@
for key in ("pip", "setuptools", "wheel"):
if key == no:
continue
+ if sys.version_info[:2] >= (3, 9) and key == "wheel":
+ continue
assert locals()[key] in files_post_first_create
diff -Nru
python-virtualenv-20.30.0+ds/tests/unit/seed/wheels/test_periodic_update.py
python-virtualenv-20.31.2+ds/tests/unit/seed/wheels/test_periodic_update.py
--- python-virtualenv-20.30.0+ds/tests/unit/seed/wheels/test_periodic_update.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/tests/unit/seed/wheels/test_periodic_update.py
2020-02-02 01:00:00.000000000 +0100
@@ -74,7 +74,7 @@
packages[args[1]["distribution"]].append(args[1]["for_py_version"])
packages = {key: sorted(value) for key, value in packages.items()}
versions = sorted(BUNDLE_SUPPORT.keys())
- expected = {"setuptools": versions, "wheel": versions, "pip": versions}
+ expected = {"setuptools": versions, "wheel": ["3.8"], "pip": versions}
assert packages == expected
@@ -101,8 +101,6 @@
"--no-pip",
"--setuptools",
"bundle",
- "--wheel",
- "bundle",
],
)
diff -Nru
python-virtualenv-20.30.0+ds/tests/unit/seed/wheels/test_wheels_util.py
python-virtualenv-20.31.2+ds/tests/unit/seed/wheels/test_wheels_util.py
--- python-virtualenv-20.30.0+ds/tests/unit/seed/wheels/test_wheels_util.py
2020-02-02 01:00:00.000000000 +0100
+++ python-virtualenv-20.31.2+ds/tests/unit/seed/wheels/test_wheels_util.py
2020-02-02 01:00:00.000000000 +0100
@@ -29,3 +29,8 @@
def test_wheel_repr():
wheel = get_embed_wheel("setuptools", MAX)
assert str(wheel.path) in repr(wheel)
+
+
+def test_unknown_distribution():
+ wheel = get_embed_wheel("unknown", MAX)
+ assert wheel is None
--- End Message ---