diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 24c407b586..c74a2d56c8 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 71.0.0 +current_version = 71.0.4 commit = True tag = True diff --git a/MANIFEST.in b/MANIFEST.in index c4f12dc68a..092612cb21 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,7 +2,7 @@ recursive-include setuptools *.py *.exe *.xml *.tmpl recursive-include tests *.py recursive-include setuptools/tests *.html recursive-include docs *.py *.txt *.rst *.conf *.css *.css_t Makefile indexsidebar.html -recursive-include setuptools/_vendor *.py *.txt +recursive-include setuptools/_vendor * recursive-include pkg_resources *.py *.txt recursive-include pkg_resources/tests/data * recursive-include tools * diff --git a/NEWS.rst b/NEWS.rst index 52b10f837b..9065b038b7 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,10 +1,46 @@ +v71.0.4 +======= + +Bugfixes +-------- + +- Removed lingering unused code around Distribution._patched_dist. (#4489) + + +v71.0.3 +======= + +Bugfixes +-------- + +- Reset the backports module when enabling vendored packages. (#4476) + + +v71.0.2 +======= + +Bugfixes +-------- + +- Include all vendored files in the sdist. (#4480) + + +v71.0.1 +======= + +Bugfixes +-------- + +- Restored package data that went missing in 71.0. This change also incidentally causes tests to be installed once again. (#4475) + + v71.0.0 ======= Deprecations and Removals ------------------------- -- Now setuptools declares its own dependencies in the ``core`` extra. Dependencies are still vendored for bootstrapping purposes, but setuptools will prefer installed dependencies if present. The ``core`` extra is used for informational purposes and should *not* be declared in package metadata (e.g. ``build-requires``). Downstream packagers can de-vendor by simply removing the ``setuptools/_vendor`` directory. (#2825) +- Now setuptools declares its own dependencies in the ``core`` extra. Dependencies are still vendored for bootstrapping purposes, but setuptools will prefer installed dependencies if present. The ``core`` extra is used for informational purposes and should *not* be declared in package metadata (e.g. ``build-requires``). Downstream packagers can de-vendor by simply removing the ``setuptools/_vendor`` directory. Since Setuptools now prefers installed dependencies, those installing to an environment with old, incompatible dependencies will not work. In that case, either uninstall the incompatible dependencies or upgrade them to satisfy those declared in ``core``. (#2825) v70.3.0 diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index ad974222ce..3c88d8d3d7 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -76,6 +76,8 @@ import _imp sys.path.extend(((vendor_path := os.path.join(os.path.dirname(os.path.dirname(__file__)), 'setuptools', '_vendor')) not in sys.path) * [vendor_path]) # fmt: skip +# workaround for #4476 +sys.modules.pop('backports', None) # capture these to bypass sandboxing from os import utime @@ -103,7 +105,7 @@ from platformdirs import user_cache_dir as _user_cache_dir if TYPE_CHECKING: - from _typeshed import StrPath, BytesPath, StrOrBytesPath + from _typeshed import BytesPath, StrPath, StrOrBytesPath from typing_extensions import Self warnings.warn( @@ -2647,6 +2649,7 @@ def _normalize_cached(filename: StrPath) -> str: ... @overload def _normalize_cached(filename: BytesPath) -> bytes: ... def _normalize_cached(filename: StrOrBytesPath) -> str | bytes: ... + else: @functools.lru_cache(maxsize=None) diff --git a/pyproject.toml b/pyproject.toml index 54931e2ff2..020f57ee17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ backend-path = ["."] [project] name = "setuptools" -version = "71.0.0" +version = "71.0.4" authors = [ { name = "Python Packaging Authority", email = "distutils-sig@python.org" }, ] @@ -175,9 +175,7 @@ PKG-INFO = "setuptools.command.egg_info:write_pkg_info" "dependency_links.txt" = "setuptools.command.egg_info:overwrite_arg" [tool.setuptools] -# disabled as it causes tests to be included #2505 -# include_package_data = true -include-package-data = false +include-package-data = true [tool.setuptools.packages.find] include = [ @@ -191,10 +189,6 @@ exclude = [ ] namespaces = true -[tool.setuptools.package-data] -# ensure that `setuptools/_vendor/jaraco/text/Lorem ipsum.txt` is installed -"*" = ["*.txt"] - [tool.distutils.sdist] formats = "zip" diff --git a/pytest.ini b/pytest.ini index e49b81561a..292b65864c 100644 --- a/pytest.ini +++ b/pytest.ini @@ -4,7 +4,6 @@ addopts= --doctest-modules --import-mode importlib --doctest-glob=pkg_resources/api_tests.txt - -r sxX consider_namespace_packages=true filterwarnings= # Fail on warnings diff --git a/ruff.toml b/ruff.toml index 1868e4aa94..09f256d5cb 100644 --- a/ruff.toml +++ b/ruff.toml @@ -7,6 +7,7 @@ exclude = [ [lint] extend-select = [ "C901", + "PERF401", "W", # local @@ -51,12 +52,16 @@ ignore = [ # Only enforcing return type annotations for public modules "**/tests/**" = ["ANN2"] "tools/**" = ["ANN2"] +# Suppress nuisance warnings about module-import-not-at-top-of-file (E402) due to workaround for #4476 +"setuptools/__init__.py" = ["E402"] +"pkg_resources/__init__.py" = ["E402"] [lint.flake8-annotations] ignore-fully-untyped = true [format] -# Enable preview to get hugged parenthesis unwrapping +# Enable preview to get hugged parenthesis unwrapping and other nice surprises +# See https://github.com/jaraco/skeleton/pull/133#issuecomment-2239538373 preview = true -# https://docs.astral.sh/ruff/settings/#format-quote-style +# https://docs.astral.sh/ruff/settings/#format_quote-style quote-style = "preserve" diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 8b0e494f01..afca08be9c 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -7,6 +7,8 @@ from typing import TYPE_CHECKING sys.path.extend(((vendor_path := os.path.join(os.path.dirname(os.path.dirname(__file__)), 'setuptools', '_vendor')) not in sys.path) * [vendor_path]) # fmt: skip +# workaround for #4476 +sys.modules.pop('backports', None) import _distutils_hack.override # noqa: F401 import distutils.core diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 9e63a934e6..30b62f5f2e 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -250,17 +250,6 @@ def finalize_options(self): # self.distribution.metadata.version = self.egg_version - # If we bootstrapped around the lack of a PKG-INFO, as might be the - # case in a fresh checkout, make sure that any special tags get added - # to the version info - # - pd = self.distribution._patched_dist - key = getattr(pd, "key", None) or getattr(pd, "name", None) - if pd is not None and key == self.egg_name.lower(): - pd._version = self.egg_version - pd._parsed_version = packaging.version.Version(self.egg_version) - self.distribution._patched_dist = None - def _get_egg_basename(self, py_version=PY_MAJOR, platform=None): """Compute filename of the output egg. Private API.""" return _egg_basename(self.egg_name, self.egg_version, py_version, platform) diff --git a/setuptools/dist.py b/setuptools/dist.py index bcab50ba65..b4496ab986 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -6,7 +6,6 @@ import os import re import sys -from contextlib import suppress from glob import iglob from pathlib import Path from typing import TYPE_CHECKING, MutableMapping @@ -28,7 +27,6 @@ from packaging.version import Version from . import _entry_points -from . import _normalization from . import _reqs from . import command as _ # noqa -- imported for side-effects from ._importlib import metadata @@ -269,24 +267,9 @@ class Distribution(_Distribution): 'extras_require': dict, } - _patched_dist = None # Used by build_py, editable_wheel and install_lib commands for legacy namespaces namespace_packages: list[str] #: :meta private: DEPRECATED - def patch_missing_pkg_info(self, attrs): - # Fake up a replacement for the data that would normally come from - # PKG-INFO, but which might not yet be built if this is a fresh - # checkout. - # - if not attrs or 'name' not in attrs or 'version' not in attrs: - return - name = _normalization.safe_name(str(attrs['name'])).lower() - with suppress(metadata.PackageNotFoundError): - dist = metadata.distribution(name) - if dist is not None and not dist.read_text('PKG-INFO'): - dist._version = _normalization.safe_version(str(attrs['version'])) - self._patched_dist = dist - def __init__(self, attrs: MutableMapping | None = None) -> None: have_package_data = hasattr(self, "package_data") if not have_package_data: @@ -295,7 +278,6 @@ def __init__(self, attrs: MutableMapping | None = None) -> None: self.dist_files: list[tuple[str, str, str]] = [] # Filter-out setuptools' specific options. self.src_root = attrs.pop("src_root", None) - self.patch_missing_pkg_info(attrs) self.dependency_links = attrs.pop('dependency_links', []) self.setup_requires = attrs.pop('setup_requires', []) for ep in metadata.entry_points(group='distutils.setup_keywords'): diff --git a/setuptools/tests/config/test_apply_pyprojecttoml.py b/setuptools/tests/config/test_apply_pyprojecttoml.py index 6b3ee9cf1e..ff9c5fc66e 100644 --- a/setuptools/tests/config/test_apply_pyprojecttoml.py +++ b/setuptools/tests/config/test_apply_pyprojecttoml.py @@ -12,7 +12,6 @@ from inspect import cleandoc from pathlib import Path from unittest.mock import Mock -from zipfile import ZipFile import pytest from ini2toml.api import LiteTranslator @@ -422,11 +421,6 @@ def test_example_file_in_sdist(self, setuptools_sdist): with tarfile.open(setuptools_sdist) as tar: assert any(name.endswith(EXAMPLES_FILE) for name in tar.getnames()) - def test_example_file_not_in_wheel(self, setuptools_wheel): - """Meta test to ensure auxiliary test files are not in wheel""" - with ZipFile(setuptools_wheel) as zipfile: - assert not any(name.endswith(EXAMPLES_FILE) for name in zipfile.namelist()) - class TestInteropCommandLineParsing: def test_version(self, tmp_path, monkeypatch, capsys): diff --git a/setuptools/tests/test_setuptools.py b/setuptools/tests/test_setuptools.py index 0c5b1f18fa..566af6980e 100644 --- a/setuptools/tests/test_setuptools.py +++ b/setuptools/tests/test_setuptools.py @@ -1,5 +1,6 @@ """Tests for the 'setuptools' package""" +import re import sys import os import distutils.core @@ -301,9 +302,26 @@ def test_findall_missing_symlink(tmpdir, can_symlink): assert found == [] +@pytest.mark.xfail(reason="unable to exclude tests; #4475 #3260") def test_its_own_wheel_does_not_contain_tests(setuptools_wheel): with ZipFile(setuptools_wheel) as zipfile: contents = [f.replace(os.sep, '/') for f in zipfile.namelist()] for member in contents: assert '/tests/' not in member + + +def test_wheel_includes_cli_scripts(setuptools_wheel): + with ZipFile(setuptools_wheel) as zipfile: + contents = [f.replace(os.sep, '/') for f in zipfile.namelist()] + + assert any('cli-64.exe' in member for member in contents) + + +def test_wheel_includes_vendored_metadata(setuptools_wheel): + with ZipFile(setuptools_wheel) as zipfile: + contents = [f.replace(os.sep, '/') for f in zipfile.namelist()] + + assert any( + re.search(r'_vendor/.*\.dist-info/METADATA', member) for member in contents + )