diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60bf6621d..a55f58807 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,17 +14,17 @@ repos: - id: tox-ini-fmt args: ["-p", "fix"] - repo: https://github.com/tox-dev/pyproject-fmt - rev: "0.13.0" + rev: "0.13.1" hooks: - id: pyproject-fmt - additional_dependencies: ["tox>=4.6.4"] + additional_dependencies: ["tox>=4.8"] - repo: https://github.com/pre-commit/mirrors-prettier - rev: "v3.0.1" + rev: "v3.0.2" hooks: - id: prettier args: ["--print-width=120", "--prose-wrap=always"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.0.282" + rev: "v0.0.285" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/README.md b/README.md index 024718331..7c98b12b5 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/virtualenv?style=flat-square)](https://pypi.org/project/virtualenv) [![Documentation](https://readthedocs.org/projects/virtualenv/badge/?version=latest&style=flat-square)](http://virtualenv.pypa.io) [![Discord](https://img.shields.io/discord/803025117553754132)](https://discord.gg/pypa) -[![PyPI - Downloads](https://img.shields.io/pypi/dm/virtualenv?style=flat-square)](https://pypistats.org/packages/virtualenv) +[![Downloads](https://static.pepy.tech/badge/virtualenv/month)](https://pepy.tech/project/virtualenv) [![PyPI - License](https://img.shields.io/pypi/l/virtualenv?style=flat-square)](https://opensource.org/licenses/MIT) [![Build Status](https://github.com/pypa/virtualenv/workflows/check/badge.svg?branch=main&event=push)](https://github.com/pypa/virtualenv/actions?query=workflow%3Acheck) [![Code style: diff --git a/docs/changelog.rst b/docs/changelog.rst index e389002d0..6a193cba3 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,17 @@ Release History .. towncrier release notes start +v20.24.4 (2023-08-30) +--------------------- + +Bugfixes - 20.24.4 +~~~~~~~~~~~~~~~~~~ +- Upgrade embedded wheels: + + * setuptools to ``68.1.2`` from ``68.1.0`` on ``3.8+`` + * wheel to ``0.41.2`` from ``0.41.1`` on ``3.7+`` (:issue:`2628`) + + v20.24.3 (2023-08-11) --------------------- diff --git a/docs/extend.rst b/docs/extend.rst index ba2a6fe75..940e783e1 100644 --- a/docs/extend.rst +++ b/docs/extend.rst @@ -73,7 +73,7 @@ under and entry point with key ``virtualenv.seed`` , and the class must implemen Activation scripts ------------------ If you want add an activator for a new shell you can do this by implementing a new activator. They must be registered -under and entry point with key ``virtualenv.activate`` , and the class must implement +under an entry point with key ``virtualenv.activate`` , and the class must implement :class:`virtualenv.activation.activator.Activator`: .. code-block:: ini diff --git a/docs/render_cli.py b/docs/render_cli.py index 71e79ab68..af74b8b02 100644 --- a/docs/render_cli.py +++ b/docs/render_cli.py @@ -1,9 +1,8 @@ from __future__ import annotations from argparse import SUPPRESS -from collections import namedtuple from contextlib import contextmanager -from typing import Any, ClassVar +from typing import Any, ClassVar, NamedTuple from docutils import nodes as n from docutils.parsers.rst.directives import unchanged_required @@ -12,9 +11,17 @@ from virtualenv.run.plugin.base import ComponentBuilder -TableRow = namedtuple("TableRow", ["names", "default", "choices", "help"]) -TextAsDefault = namedtuple("TextAsDefault", ["text"]) +class TableRow(NamedTuple): + names: list[str] + default: str + choices: set[str] + help: str # noqa: A003 + + +class TextAsDefault(NamedTuple): + text: str + CUSTOM = { "discovery": ComponentBuilder.entry_points_for("virtualenv.discovery"), diff --git a/docs/user_guide.rst b/docs/user_guide.rst index 2169dfe07..b5534c860 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -228,7 +228,7 @@ contain some executable, this will still resolve to the same executable it would For a list of shells we provide activators see :option:`activators`. The location of these is right alongside the Python executables: usually ``Scripts`` folder on Windows, ``bin`` on POSIX. They are called ``activate``, plus an -extension that's specific per activator, with no extension for Bash. You can invoke them, usally by source-ing them. +extension that's specific per activator, with no extension for Bash. You can invoke them, usually by source-ing them. The source command might vary by shell - e.g. on Bash it’s ``source`` (or ``.``): .. code-block:: console diff --git a/pyproject.toml b/pyproject.toml index 61af41f80..8df35ef57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,9 +47,9 @@ dependencies = [ "platformdirs<4,>=3.9.1", ] optional-dependencies.docs = [ - "furo>=2023.5.20", + "furo>=2023.7.26", "proselint>=0.13", - "sphinx>=7.0.1", + "sphinx>=7.1.2", "sphinx-argparse>=0.4", "sphinxcontrib-towncrier>=0.2.1a0", "towncrier>=23.6", diff --git a/src/virtualenv/create/creator.py b/src/virtualenv/create/creator.py index 06f9d39ba..8ff54166e 100644 --- a/src/virtualenv/create/creator.py +++ b/src/virtualenv/create/creator.py @@ -121,7 +121,7 @@ def non_write_able(dest, value): if trip == char: continue raise ValueError(trip) # noqa: TRY301 - except ValueError: # noqa: PERF203 + except ValueError: refused[char] = None if refused: bad = "".join(refused.keys()) diff --git a/src/virtualenv/discovery/py_info.py b/src/virtualenv/discovery/py_info.py index a32c3f2b7..8b59130a4 100644 --- a/src/virtualenv/discovery/py_info.py +++ b/src/virtualenv/discovery/py_info.py @@ -17,7 +17,7 @@ from collections import OrderedDict, namedtuple from string import digits -VersionInfo = namedtuple("VersionInfo", ["major", "minor", "micro", "releaselevel", "serial"]) +VersionInfo = namedtuple("VersionInfo", ["major", "minor", "micro", "releaselevel", "serial"]) # noqa: PYI024 def _get_path_extensions(): diff --git a/src/virtualenv/discovery/windows/pep514.py b/src/virtualenv/discovery/windows/pep514.py index 9d5691aa4..8bc9e3060 100644 --- a/src/virtualenv/discovery/windows/pep514.py +++ b/src/virtualenv/discovery/windows/pep514.py @@ -139,7 +139,7 @@ def parse_version(version_str): def msg(path, what): - LOGGER.warning(f"PEP-514 violation in Windows Registry at {path} error: {what}") + LOGGER.warning("PEP-514 violation in Windows Registry at %s error: %s", path, what) def _run(): diff --git a/src/virtualenv/run/plugin/base.py b/src/virtualenv/run/plugin/base.py index 71ce5c4f4..16114f60e 100644 --- a/src/virtualenv/run/plugin/base.py +++ b/src/virtualenv/run/plugin/base.py @@ -25,9 +25,9 @@ def entry_points_for(cls, key): @staticmethod def entry_points(): - if PluginLoader._ENTRY_POINTS is None: # noqa: SLF001 - PluginLoader._ENTRY_POINTS = entry_points() # noqa: SLF001 - return PluginLoader._ENTRY_POINTS # noqa: SLF001 + if PluginLoader._ENTRY_POINTS is None: + PluginLoader._ENTRY_POINTS = entry_points() + return PluginLoader._ENTRY_POINTS class ComponentBuilder(PluginLoader): diff --git a/src/virtualenv/run/plugin/creators.py b/src/virtualenv/run/plugin/creators.py index e5f8d682f..a0bcb028b 100644 --- a/src/virtualenv/run/plugin/creators.py +++ b/src/virtualenv/run/plugin/creators.py @@ -1,13 +1,22 @@ from __future__ import annotations -from collections import OrderedDict, defaultdict, namedtuple +from collections import OrderedDict, defaultdict +from typing import TYPE_CHECKING, NamedTuple from virtualenv.create.describe import Describe from virtualenv.create.via_global_ref.builtin.builtin_way import VirtualenvBuiltin from .base import ComponentBuilder -CreatorInfo = namedtuple("CreatorInfo", ["key_to_class", "key_to_meta", "describe", "builtin_key"]) +if TYPE_CHECKING: + from virtualenv.create.creator import Creator, CreatorMeta + + +class CreatorInfo(NamedTuple): + key_to_class: dict[str, type[Creator]] + key_to_meta: dict[str, CreatorMeta] + describe: type[Describe] | None + builtin_key: str class CreatorSelector(ComponentBuilder): diff --git a/src/virtualenv/seed/wheels/embed/__init__.py b/src/virtualenv/seed/wheels/embed/__init__.py index 0d87e4b28..fcbb35cc4 100644 --- a/src/virtualenv/seed/wheels/embed/__init__.py +++ b/src/virtualenv/seed/wheels/embed/__init__.py @@ -9,32 +9,32 @@ "3.7": { "pip": "pip-23.2.1-py3-none-any.whl", "setuptools": "setuptools-68.0.0-py3-none-any.whl", - "wheel": "wheel-0.41.1-py3-none-any.whl", + "wheel": "wheel-0.41.2-py3-none-any.whl", }, "3.8": { "pip": "pip-23.2.1-py3-none-any.whl", - "setuptools": "setuptools-68.0.0-py3-none-any.whl", - "wheel": "wheel-0.41.1-py3-none-any.whl", + "setuptools": "setuptools-68.1.2-py3-none-any.whl", + "wheel": "wheel-0.41.2-py3-none-any.whl", }, "3.9": { "pip": "pip-23.2.1-py3-none-any.whl", - "setuptools": "setuptools-68.0.0-py3-none-any.whl", - "wheel": "wheel-0.41.1-py3-none-any.whl", + "setuptools": "setuptools-68.1.2-py3-none-any.whl", + "wheel": "wheel-0.41.2-py3-none-any.whl", }, "3.10": { "pip": "pip-23.2.1-py3-none-any.whl", - "setuptools": "setuptools-68.0.0-py3-none-any.whl", - "wheel": "wheel-0.41.1-py3-none-any.whl", + "setuptools": "setuptools-68.1.2-py3-none-any.whl", + "wheel": "wheel-0.41.2-py3-none-any.whl", }, "3.11": { "pip": "pip-23.2.1-py3-none-any.whl", - "setuptools": "setuptools-68.0.0-py3-none-any.whl", - "wheel": "wheel-0.41.1-py3-none-any.whl", + "setuptools": "setuptools-68.1.2-py3-none-any.whl", + "wheel": "wheel-0.41.2-py3-none-any.whl", }, "3.12": { "pip": "pip-23.2.1-py3-none-any.whl", - "setuptools": "setuptools-68.0.0-py3-none-any.whl", - "wheel": "wheel-0.41.1-py3-none-any.whl", + "setuptools": "setuptools-68.1.2-py3-none-any.whl", + "wheel": "wheel-0.41.2-py3-none-any.whl", }, } MAX = "3.7" diff --git a/src/virtualenv/seed/wheels/embed/setuptools-68.1.2-py3-none-any.whl b/src/virtualenv/seed/wheels/embed/setuptools-68.1.2-py3-none-any.whl new file mode 100644 index 000000000..e9fdff1cd Binary files /dev/null and b/src/virtualenv/seed/wheels/embed/setuptools-68.1.2-py3-none-any.whl differ diff --git a/src/virtualenv/seed/wheels/embed/wheel-0.41.1-py3-none-any.whl b/src/virtualenv/seed/wheels/embed/wheel-0.41.2-py3-none-any.whl similarity index 72% rename from src/virtualenv/seed/wheels/embed/wheel-0.41.1-py3-none-any.whl rename to src/virtualenv/seed/wheels/embed/wheel-0.41.2-py3-none-any.whl index 17e32b39a..f2befff47 100644 Binary files a/src/virtualenv/seed/wheels/embed/wheel-0.41.1-py3-none-any.whl and b/src/virtualenv/seed/wheels/embed/wheel-0.41.2-py3-none-any.whl differ diff --git a/src/virtualenv/seed/wheels/periodic_update.py b/src/virtualenv/seed/wheels/periodic_update.py index 3d0239d4d..95937e636 100644 --- a/src/virtualenv/seed/wheels/periodic_update.py +++ b/src/virtualenv/seed/wheels/periodic_update.py @@ -353,7 +353,7 @@ def _pypi_get_distribution_info(distribution): with urlopen(url, context=context) as file_handler: # noqa: S310 content = json.load(file_handler) break - except URLError as exception: # noqa: PERF203 + except URLError as exception: logging.error("failed to access %s because %r", url, exception) # noqa: TRY400 except Exception as exception: # noqa: BLE001 logging.error("failed to access %s because %r", url, exception) # noqa: TRY400 diff --git a/src/virtualenv/util/path/_permission.py b/src/virtualenv/util/path/_permission.py index f3e9b625c..8dcad0ce9 100644 --- a/src/virtualenv/util/path/_permission.py +++ b/src/virtualenv/util/path/_permission.py @@ -14,7 +14,7 @@ def make_exe(filename): mode |= level filename.chmod(mode) break - except OSError: # noqa: PERF203 + except OSError: continue diff --git a/tasks/make_zipapp.py b/tasks/make_zipapp.py index be211c4cb..bc74834e5 100644 --- a/tasks/make_zipapp.py +++ b/tasks/make_zipapp.py @@ -162,7 +162,7 @@ def get_dependencies(whl, version): m for m in markers if isinstance(m, tuple) and len(m) == 3 and m[0].value == "extra" # noqa: PLR2004 ): continue - py_versions = WheelDownloader._marker_at(markers, "python_version") # noqa: SLF001 + py_versions = WheelDownloader._marker_at(markers, "python_version") if py_versions: marker = Marker('python_version < "1"') marker._markers = [ # noqa: SLF001 @@ -173,13 +173,13 @@ def get_dependencies(whl, version): continue deleted = 0 for ver in py_versions: - deleted += WheelDownloader._del_marker_at(markers, ver - deleted) # noqa: SLF001 + deleted += WheelDownloader._del_marker_at(markers, ver - deleted) platforms = [] - platform_positions = WheelDownloader._marker_at(markers, "sys_platform") # noqa: SLF001 + platform_positions = WheelDownloader._marker_at(markers, "sys_platform") deleted = 0 for pos in platform_positions: # can only be ore meaningfully platform = f"{markers[pos][1].value}{markers[pos][2].value}" - deleted += WheelDownloader._del_marker_at(markers, pos - deleted) # noqa: SLF001 + deleted += WheelDownloader._del_marker_at(markers, pos - deleted) platforms.append(platform) if not platforms: platforms.append(None) diff --git a/tasks/upgrade_wheels.py b/tasks/upgrade_wheels.py index daa289424..ee5c15b64 100644 --- a/tasks/upgrade_wheels.py +++ b/tasks/upgrade_wheels.py @@ -120,7 +120,7 @@ def get_embed_wheel(distribution, for_py_version): dest_target = DEST / "__init__.py" dest_target.write_text(msg, encoding="utf-8") - subprocess.run([sys.executable, "-m", "black", str(dest_target)]) # noqa: S603 + subprocess.run([sys.executable, "-m", "black", str(dest_target)], check=False) # noqa: S603 raise SystemExit(outcome) diff --git a/tests/unit/discovery/py_info/test_py_info.py b/tests/unit/discovery/py_info/test_py_info.py index 89c98dfc4..11e63285b 100644 --- a/tests/unit/discovery/py_info/test_py_info.py +++ b/tests/unit/discovery/py_info/test_py_info.py @@ -8,9 +8,9 @@ import os import sys import sysconfig -from collections import namedtuple from pathlib import Path from textwrap import dedent +from typing import NamedTuple import pytest @@ -166,7 +166,10 @@ def test_py_info_cached_symlink(mocker, tmp_path, session_app_data): assert spy.call_count == count + 1 # no longer needed the host invocation, but the new symlink is must -PyInfoMock = namedtuple("PyInfoMock", ["implementation", "architecture", "version_info"]) +class PyInfoMock(NamedTuple): + implementation: str + architecture: int + version_info: VersionInfo @pytest.mark.parametrize(