diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 81716941c..f488cae26 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -70,8 +70,12 @@ jobs: brew cleanup && brew upgrade python@$PY || brew install python@$PY echo "/usr/local/opt/python@$PY/libexec/bin" >>"${GITHUB_PATH}" shell: bash + - name: Install tox-uv + run: python -m pip install tox-uv pip -U + if: "!(startsWith(matrix.py,'pypy') || matrix.py == '3.7' || matrix.py == 'brew@3.9' || matrix.py == 'brew@3.8')" - name: Install tox run: python -m pip install tox pip -U + if: "(startsWith(matrix.py,'pypy') || matrix.py == '3.7' || matrix.py == 'brew@3.9' || matrix.py == 'brew@3.8')" - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -128,7 +132,7 @@ jobs: with: python-version: "3.12" - name: Install tox - run: python -m pip install tox + run: python -m pip install tox-uv - name: Setup check run: python -m tox --skip-missing-interpreters false -e ${{ matrix.tox_env }} --notest - name: Run check for ${{ matrix.tox_env }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed3547b3a..22ce01193 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.28.0 + rev: 0.28.2 hooks: - id: check-github-workflows args: [ "--verbose" ] @@ -25,7 +25,7 @@ repos: - id: pyproject-fmt additional_dependencies: ["tox>=4.12.1"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.3.3" + rev: "v0.3.7" hooks: - id: ruff-format - id: ruff diff --git a/docs/changelog/2699.bugfix.rst b/docs/changelog/2699.bugfix.rst new file mode 100644 index 000000000..5925ea5a5 --- /dev/null +++ b/docs/changelog/2699.bugfix.rst @@ -0,0 +1,4 @@ +Upgrade embedded wheels: + +- setuptools of ``69.1.0`` to ``69.5.1`` +- wheel of ``0.42.0`` to ``0.43.0`` diff --git a/pyproject.toml b/pyproject.toml index a6c06d7cc..0aaa3db7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ dependencies = [ optional-dependencies.docs = [ "furo>=2023.7.26", "proselint>=0.13", - "sphinx>=7.1.2", + "sphinx!=7.3,>=7.1.2", "sphinx-argparse>=0.4", "sphinxcontrib-towncrier>=0.2.1a0", "towncrier>=23.6", diff --git a/src/virtualenv/discovery/builtin.py b/src/virtualenv/discovery/builtin.py index 081bb22cf..c81439ce6 100644 --- a/src/virtualenv/discovery/builtin.py +++ b/src/virtualenv/discovery/builtin.py @@ -14,7 +14,7 @@ class Builtin(Discover): def __init__(self, options) -> None: super().__init__(options) - self.python_spec = options.python if options.python else [sys.executable] + self.python_spec = options.python or [sys.executable] self.app_data = options.app_data self.try_first_with = options.try_first_with @@ -155,7 +155,7 @@ def __repr__(self) -> str: def check_path(candidate, path): _, ext = os.path.splitext(candidate) if sys.platform == "win32" and ext != ".exe": - candidate = candidate + ".exe" + candidate += ".exe" if os.path.isfile(candidate): return candidate candidate = os.path.join(path, candidate) diff --git a/src/virtualenv/discovery/py_info.py b/src/virtualenv/discovery/py_info.py index da1619faf..666ece37d 100644 --- a/src/virtualenv/discovery/py_info.py +++ b/src/virtualenv/discovery/py_info.py @@ -112,8 +112,7 @@ def abs_path(v): config_var_keys = set() for element in self.sysconfig_paths.values(): - for k in _CONF_VAR_RE.findall(element): - config_var_keys.add(k[1:-1]) + config_var_keys.update(k[1:-1] for k in _CONF_VAR_RE.findall(element)) config_var_keys.add("PYTHONFRAMEWORK") self.sysconfig_vars = {i: sysconfig.get_config_var(i or "") for i in config_var_keys} diff --git a/src/virtualenv/report.py b/src/virtualenv/report.py index db1be9934..9ad52a12a 100644 --- a/src/virtualenv/report.py +++ b/src/virtualenv/report.py @@ -18,8 +18,7 @@ def setup_report(verbosity, show_pid=False): # noqa: FBT002 _clean_handlers(LOGGER) - if verbosity > MAX_LEVEL: - verbosity = MAX_LEVEL # pragma: no cover + verbosity = min(verbosity, MAX_LEVEL) # pragma: no cover level = LEVELS[verbosity] msg_format = "%(message)s" if level <= logging.DEBUG: diff --git a/src/virtualenv/seed/embed/via_app_data/pip_install/symlink.py b/src/virtualenv/seed/embed/via_app_data/pip_install/symlink.py index 6bc5e51c0..1ffefc6f1 100644 --- a/src/virtualenv/seed/embed/via_app_data/pip_install/symlink.py +++ b/src/virtualenv/seed/embed/via_app_data/pip_install/symlink.py @@ -40,8 +40,7 @@ def _generate_new_files(self): def _fix_records(self, new_files): new_files.update(i for i in self._image_dir.iterdir()) extra_record_data_str = self._records_text(sorted(new_files, key=str)) - with open(str(self._dist_info / "RECORD"), "wb") as file_handler: - file_handler.write(extra_record_data_str.encode("utf-8")) + (self._dist_info / "RECORD").write_text(extra_record_data_str, encoding="utf-8") def build_image(self): super().build_image() diff --git a/src/virtualenv/seed/wheels/embed/__init__.py b/src/virtualenv/seed/wheels/embed/__init__.py index 04334f901..dedcadfa4 100644 --- a/src/virtualenv/seed/wheels/embed/__init__.py +++ b/src/virtualenv/seed/wheels/embed/__init__.py @@ -13,33 +13,33 @@ }, "3.8": { "pip": "pip-24.0-py3-none-any.whl", - "setuptools": "setuptools-69.1.0-py3-none-any.whl", - "wheel": "wheel-0.42.0-py3-none-any.whl", + "setuptools": "setuptools-69.5.1-py3-none-any.whl", + "wheel": "wheel-0.43.0-py3-none-any.whl", }, "3.9": { "pip": "pip-24.0-py3-none-any.whl", - "setuptools": "setuptools-69.1.0-py3-none-any.whl", - "wheel": "wheel-0.42.0-py3-none-any.whl", + "setuptools": "setuptools-69.5.1-py3-none-any.whl", + "wheel": "wheel-0.43.0-py3-none-any.whl", }, "3.10": { "pip": "pip-24.0-py3-none-any.whl", - "setuptools": "setuptools-69.1.0-py3-none-any.whl", - "wheel": "wheel-0.42.0-py3-none-any.whl", + "setuptools": "setuptools-69.5.1-py3-none-any.whl", + "wheel": "wheel-0.43.0-py3-none-any.whl", }, "3.11": { "pip": "pip-24.0-py3-none-any.whl", - "setuptools": "setuptools-69.1.0-py3-none-any.whl", - "wheel": "wheel-0.42.0-py3-none-any.whl", + "setuptools": "setuptools-69.5.1-py3-none-any.whl", + "wheel": "wheel-0.43.0-py3-none-any.whl", }, "3.12": { "pip": "pip-24.0-py3-none-any.whl", - "setuptools": "setuptools-69.1.0-py3-none-any.whl", - "wheel": "wheel-0.42.0-py3-none-any.whl", + "setuptools": "setuptools-69.5.1-py3-none-any.whl", + "wheel": "wheel-0.43.0-py3-none-any.whl", }, "3.13": { "pip": "pip-24.0-py3-none-any.whl", - "setuptools": "setuptools-69.1.0-py3-none-any.whl", - "wheel": "wheel-0.42.0-py3-none-any.whl", + "setuptools": "setuptools-69.5.1-py3-none-any.whl", + "wheel": "wheel-0.43.0-py3-none-any.whl", }, } MAX = "3.7" diff --git a/src/virtualenv/seed/wheels/embed/setuptools-69.1.0-py3-none-any.whl b/src/virtualenv/seed/wheels/embed/setuptools-69.1.0-py3-none-any.whl deleted file mode 100644 index 3d83a7b75..000000000 Binary files a/src/virtualenv/seed/wheels/embed/setuptools-69.1.0-py3-none-any.whl and /dev/null differ diff --git a/src/virtualenv/seed/wheels/embed/setuptools-69.5.1-py3-none-any.whl b/src/virtualenv/seed/wheels/embed/setuptools-69.5.1-py3-none-any.whl new file mode 100644 index 000000000..4bd4c0e03 Binary files /dev/null and b/src/virtualenv/seed/wheels/embed/setuptools-69.5.1-py3-none-any.whl differ diff --git a/src/virtualenv/seed/wheels/embed/wheel-0.43.0-py3-none-any.whl b/src/virtualenv/seed/wheels/embed/wheel-0.43.0-py3-none-any.whl new file mode 100644 index 000000000..67e230871 Binary files /dev/null and b/src/virtualenv/seed/wheels/embed/wheel-0.43.0-py3-none-any.whl differ diff --git a/tasks/make_zipapp.py b/tasks/make_zipapp.py index 185d84372..f83b9fff3 100644 --- a/tasks/make_zipapp.py +++ b/tasks/make_zipapp.py @@ -279,7 +279,7 @@ def get_wheels_for_support_versions(folder): class WheelForVersion: def __init__(self, wheel=None, versions=None) -> None: self.wheel = wheel - self.versions = versions if versions else [] + self.versions = versions or [] def __repr__(self) -> str: return f"{self.__class__.__name__}({self.wheel!r}, {self.versions!r})" diff --git a/tasks/update_embedded.py b/tasks/update_embedded.py index 4d7d1984d..933e033f6 100755 --- a/tasks/update_embedded.py +++ b/tasks/update_embedded.py @@ -69,8 +69,7 @@ def handle_file(previous_content, filename, variable_name, previous_encoded): def report(exit_code, new, next_match, current, script_path): if new != current: print("Content updated; overwriting... ", end="") # noqa: T201 - with open(script_path, "w", encoding=locale.getpreferredencoding(False)) as current_fh: # noqa: FBT003 - current_fh.write(new) + script_path.write_bytes(new) print("done.") # noqa: T201 else: print("No changes in content") # noqa: T201 diff --git a/tasks/upgrade_wheels.py b/tasks/upgrade_wheels.py index 32cfaaaee..d8f1c9adb 100644 --- a/tasks/upgrade_wheels.py +++ b/tasks/upgrade_wheels.py @@ -120,7 +120,14 @@ 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", "ruff", str(dest_target), "--fix", "--unsafe-fixes"], check=False) # noqa: S603 + subprocess.run( + [sys.executable, "-m", "ruff", "check", str(dest_target), "--fix", "--unsafe-fixes"], # noqa: S603 + check=False, + ) + subprocess.run( + [sys.executable, "-m", "ruff", "format", str(dest_target), "--preview"], # noqa: S603 + check=False, + ) raise SystemExit(outcome) diff --git a/tests/unit/activation/conftest.py b/tests/unit/activation/conftest.py index fac463437..623c55d4e 100644 --- a/tests/unit/activation/conftest.py +++ b/tests/unit/activation/conftest.py @@ -47,7 +47,7 @@ def get_version(self, raise_on_fail): raise return RuntimeError(f"{self} is not available due {exception}") else: - result = out if out else err + result = out or err self._version = result return result return self._version diff --git a/tests/unit/create/test_creator.py b/tests/unit/create/test_creator.py index bb3a4c2fe..5930078f8 100644 --- a/tests/unit/create/test_creator.py +++ b/tests/unit/create/test_creator.py @@ -484,10 +484,9 @@ def test_no_preimport_threading(tmp_path): # verify that .pth files in site-packages/ are always processed even if $PYTHONPATH points to it. def test_pth_in_site_vs_python_path(tmp_path): session = cli_run([str(tmp_path)]) - site_packages = str(session.creator.purelib) + site_packages = session.creator.purelib # install test.pth that sets sys.testpth='ok' - with open(os.path.join(site_packages, "test.pth"), "w", encoding="utf-8") as f: - f.write('import sys; sys.testpth="ok"\n') + (session.creator.purelib / "test.pth").write_text('import sys; sys.testpth="ok"\n', encoding="utf-8") # verify that test.pth is activated when interpreter is run out = subprocess.check_output( [str(session.creator.exe), "-c", r"import sys; print(sys.testpth)"], @@ -497,7 +496,7 @@ def test_pth_in_site_vs_python_path(tmp_path): assert out == "ok\n" # same with $PYTHONPATH pointing to site_packages env = os.environ.copy() - path = [site_packages] + path = [str(site_packages)] if "PYTHONPATH" in env: path.append(env["PYTHONPATH"]) env["PYTHONPATH"] = os.pathsep.join(path) diff --git a/tox.ini b/tox.ini index 98e7c6854..900f7692e 100644 --- a/tox.ini +++ b/tox.ini @@ -38,12 +38,13 @@ commands = coverage report --skip-covered --show-missing coverage xml -o {toxworkdir}/coverage.{envname}.xml coverage html -d {envtmpdir}/htmlcov --show-contexts --title virtualenv-{envname}-coverage +uv_seed = true [testenv:fix] description = format the code base to adhere to our styles, and complain about what we cannot do automatically skip_install = true deps = - pre-commit>=3.6 + pre-commit>=3.7 commands = pre-commit run --all-files --show-diff-on-failure @@ -51,8 +52,8 @@ commands = description = check that the long description is valid (need for PyPI) skip_install = true deps = - build[virtualenv]>=1.0.3 - twine>=4.0.2 + build[virtualenv]>=1.2.1 + twine>=5 extras = commands = python -m build -o {envtmpdir} --wheel --sdist . @@ -70,18 +71,19 @@ commands = description = upgrade pip/wheels/setuptools to latest skip_install = true deps = - ruff>=0.2.1 + ruff>=0.3.7 pass_env = UPGRADE_ADVISORY change_dir = {toxinidir}/tasks commands = python upgrade_wheels.py +uv_seed = true [testenv:release] description = do a release, required posarg of the version number deps = - gitpython>=3.1.41 - packaging>=23.2 + gitpython>=3.1.43 + packaging>=24 towncrier>=23.11 change_dir = {toxinidir}/tasks commands = @@ -96,11 +98,13 @@ extras = commands = python -m pip list --format=columns python -c 'import sys; print(sys.executable)' +uv_seed = true [testenv:zipapp] description = generate a zipapp skip_install = true deps = - packaging>=23.2 + packaging>=24 commands = python tasks/make_zipapp.py +uv_seed = true