From 8f42595ca65133aeb4b75f38183233c27b2e6247 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 28 Feb 2025 00:19:07 +0100 Subject: [PATCH 01/16] Enable ruff rules ISC001/ISC002 (jaraco/skeleton#158) Starting with ruff 0.9.1, they are compatible with the ruff formatter when used together. --- ruff.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index b52a6d7c80..2b67926716 100644 --- a/ruff.toml +++ b/ruff.toml @@ -43,8 +43,6 @@ ignore = [ "Q003", "COM812", "COM819", - "ISC001", - "ISC002", # local ] From b7d4b6ee00804bef36a8c398676e207813540c3b Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 4 Mar 2025 03:24:14 -0500 Subject: [PATCH 02/16] remove extra spaces in ruff.toml (jaraco/skeleton#164) --- ruff.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ruff.toml b/ruff.toml index 2b67926716..1e9528466b 100644 --- a/ruff.toml +++ b/ruff.toml @@ -4,13 +4,13 @@ extend = "pyproject.toml" [lint] extend-select = [ # upstream - + "C901", # complex-structure "I", # isort "PERF401", # manual-list-comprehension "W", # pycodestyle Warning - - # Ensure modern type annotation syntax and best practices + + # Ensure modern type annotation syntax and best practices # Not including those covered by type-checkers or exclusive to Python 3.11+ "FA", # flake8-future-annotations "F404", # late-future-import @@ -26,7 +26,7 @@ extend-select = [ ] ignore = [ # upstream - + # Typeshed rejects complex or non-literal defaults for maintenance and testing reasons, # irrelevant to this project. "PYI011", # typed-argument-default-in-stub @@ -44,7 +44,7 @@ ignore = [ "COM812", "COM819", - # local + # local ] [format] From b00e9dd730423a399c1d3c3d5621687adff0c5a5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Mar 2025 09:05:55 -0500 Subject: [PATCH 03/16] Remove pycodestyle warnings, no longer meaningful when using ruff formatter. Ref https://github.com/jaraco/skeleton/commit/d1c5444126aeacefee3949b30136446ab99979d8#commitcomment-153409678 --- ruff.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index 1e9528466b..267a1ba1f1 100644 --- a/ruff.toml +++ b/ruff.toml @@ -8,7 +8,6 @@ extend-select = [ "C901", # complex-structure "I", # isort "PERF401", # manual-list-comprehension - "W", # pycodestyle Warning # Ensure modern type annotation syntax and best practices # Not including those covered by type-checkers or exclusive to Python 3.11+ From d587ff737ee89778cf6f4bbd249e770c965fee06 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:08:11 +0100 Subject: [PATCH 04/16] Update to the latest ruff version (jaraco/skeleton#166) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 04870d16bf..633e3648e9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.1 + rev: v0.9.9 hooks: - id: ruff args: [--fix, --unsafe-fixes] From ad84110008b826efd6e39bcc39b9998b4f1cc767 Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 21 Mar 2025 00:14:38 +0000 Subject: [PATCH 05/16] Remove deprecated license classifier (PEP 639) (jaraco/skeleton#170) --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 328b98cb46..71b1a7dabc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,6 @@ readme = "README.rst" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", ] From 1ebb559a507f97ece7342d7f1532a49188cade33 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 20 Mar 2025 20:56:31 -0400 Subject: [PATCH 06/16] Remove workaround and update badge. Closes jaraco/skeleton#155 --- README.rst | 2 +- ruff.toml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 4d3cabee9d..3000f5ab21 100644 --- a/README.rst +++ b/README.rst @@ -7,7 +7,7 @@ :target: https://github.com/PROJECT_PATH/actions?query=workflow%3A%22tests%22 :alt: tests -.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json +.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json :target: https://github.com/astral-sh/ruff :alt: Ruff diff --git a/ruff.toml b/ruff.toml index 267a1ba1f1..63c0825f6b 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,6 +1,3 @@ -# extend pyproject.toml for requires-python (workaround astral-sh/ruff#10299) -extend = "pyproject.toml" - [lint] extend-select = [ # upstream From 979e626055ab60095b37be04555a01a40f62e470 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 22 Mar 2025 05:33:58 -0400 Subject: [PATCH 07/16] Remove PIP_NO_PYTHON_VERSION_WARNING. Ref pypa/pip#13154 --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5841cc37b7..928acf2ca6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,6 @@ env: # Suppress noisy pip warnings PIP_DISABLE_PIP_VERSION_CHECK: 'true' - PIP_NO_PYTHON_VERSION_WARNING: 'true' PIP_NO_WARN_SCRIPT_LOCATION: 'true' # Ensure tests can sense settings about the environment From d751068fd2627d6d8f1729e39cbcd8119049998f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 31 Mar 2025 22:42:14 +0300 Subject: [PATCH 08/16] Fix typo: pyproject.license -> project.license --- NEWS.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.rst b/NEWS.rst index 554caf867c..304263eecd 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -119,7 +119,7 @@ Deprecations and Removals - Deprecated ``project.license`` as a TOML table in ``pyproject.toml``\. Users are expected to move towards using ``project.license-files`` and/or SPDX expressions (as strings) in - ``pyproject.license``\. + ``project.license``\. See PEP :pep:`639 <639#deprecate-license-key-table-subkeys>`. (#4840) - Added simple validation for given glob patterns in ``license-files``\: a warning will be generated if no file is matched. From d8390feaa99091d1ba9626bec0e4ba7072fc507a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Apr 2025 12:49:55 -0400 Subject: [PATCH 09/16] Extract _resolve_download_filename with test. --- setuptools/package_index.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 1a6abebcda..b317735097 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -807,9 +807,16 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) else: raise DistutilsError(f"Download error for {url}: {v}") from v - def _download_url(self, url, tmpdir): - # Determine download filename - # + @staticmethod + def _resolve_download_filename(url, tmpdir): + """ + >>> du = PackageIndex._resolve_download_filename + >>> root = getfixture('tmp_path') + >>> url = 'https://files.pythonhosted.org/packages/a9/5a/0db.../setuptools-78.1.0.tar.gz' + >>> import pathlib + >>> str(pathlib.Path(du(url, root)).relative_to(root)) + 'setuptools-78.1.0.tar.gz' + """ name, _fragment = egg_info_for_url(url) if name: while '..' in name: @@ -820,8 +827,13 @@ def _download_url(self, url, tmpdir): if name.endswith('.egg.zip'): name = name[:-4] # strip the extra .zip before download - filename = os.path.join(tmpdir, name) + return os.path.join(tmpdir, name) + def _download_url(self, url, tmpdir): + """ + Determine the download filename. + """ + filename = self._resolve_download_filename(url, tmpdir) return self._download_vcs(url, filename) or self._download_other(url, filename) @staticmethod From 250a6d17978f9f6ac3ac887091f2d32886fbbb0b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Apr 2025 13:03:47 -0400 Subject: [PATCH 10/16] Add a check to ensure the name resolves relative to the tmpdir. Closes #4946 --- setuptools/package_index.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index b317735097..a8f868e22b 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -810,12 +810,20 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) @staticmethod def _resolve_download_filename(url, tmpdir): """ + >>> import pathlib >>> du = PackageIndex._resolve_download_filename >>> root = getfixture('tmp_path') >>> url = 'https://files.pythonhosted.org/packages/a9/5a/0db.../setuptools-78.1.0.tar.gz' - >>> import pathlib >>> str(pathlib.Path(du(url, root)).relative_to(root)) 'setuptools-78.1.0.tar.gz' + + Ensures the target is always in tmpdir. + + >>> url = 'https://anyhost/%2fhome%2fuser%2f.ssh%2fauthorized_keys' + >>> du(url, root) + Traceback (most recent call last): + ... + ValueError: Invalid filename... """ name, _fragment = egg_info_for_url(url) if name: @@ -827,7 +835,13 @@ def _resolve_download_filename(url, tmpdir): if name.endswith('.egg.zip'): name = name[:-4] # strip the extra .zip before download - return os.path.join(tmpdir, name) + filename = os.path.join(tmpdir, name) + + # ensure path resolves within the tmpdir + if not filename.startswith(str(tmpdir)): + raise ValueError(f"Invalid filename {filename}") + + return filename def _download_url(self, url, tmpdir): """ From e409e8002932f2b86aae7b1abc8f8c2ebf96df2c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Apr 2025 13:35:30 -0400 Subject: [PATCH 11/16] Extract _sanitize method for sanitizing the filename. --- setuptools/package_index.py | 58 +++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index a8f868e22b..fdd0c825bf 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -808,7 +808,36 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) raise DistutilsError(f"Download error for {url}: {v}") from v @staticmethod - def _resolve_download_filename(url, tmpdir): + def _sanitize(name): + r""" + Replace unsafe path directives with underscores. + + >>> san = PackageIndex._sanitize + >>> san('/home/user/.ssh/authorized_keys') + '_home_user_.ssh_authorized_keys' + >>> san('..\\foo\\bing') + '__foo_bing' + >>> san('D:bar') + 'D_bar' + >>> san('C:\\bar') + 'C__bar' + >>> san('foo..bar') + 'foo..bar' + >>> san('D:../foo') + 'D___foo' + """ + pattern = '|'.join(( + # drive letters + r':', + # path separators + r'[/\\]', + # parent dirs + r'(?:(?<=([/\\]|:))\.\.(?=[/\\]|$))|(?:^\.\.(?=[/\\]|$))', + )) + return re.sub(pattern, r'_', name) + + @classmethod + def _resolve_download_filename(cls, url, tmpdir): """ >>> import pathlib >>> du = PackageIndex._resolve_download_filename @@ -816,32 +845,19 @@ def _resolve_download_filename(url, tmpdir): >>> url = 'https://files.pythonhosted.org/packages/a9/5a/0db.../setuptools-78.1.0.tar.gz' >>> str(pathlib.Path(du(url, root)).relative_to(root)) 'setuptools-78.1.0.tar.gz' - - Ensures the target is always in tmpdir. - - >>> url = 'https://anyhost/%2fhome%2fuser%2f.ssh%2fauthorized_keys' - >>> du(url, root) - Traceback (most recent call last): - ... - ValueError: Invalid filename... """ name, _fragment = egg_info_for_url(url) - if name: - while '..' in name: - name = name.replace('..', '.').replace('\\', '_') - else: - name = "__downloaded__" # default if URL has no path contents + name = cls._sanitize( + name + or + # default if URL has no path contents + '__downloaded__' + ) if name.endswith('.egg.zip'): name = name[:-4] # strip the extra .zip before download - filename = os.path.join(tmpdir, name) - - # ensure path resolves within the tmpdir - if not filename.startswith(str(tmpdir)): - raise ValueError(f"Invalid filename {filename}") - - return filename + return os.path.join(tmpdir, name) def _download_url(self, url, tmpdir): """ From 2ca4a9fe4758fcd39d771d3d3a5b4840aacebdf7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Apr 2025 13:39:54 -0400 Subject: [PATCH 12/16] Rely on re.sub to perform the decision in one expression. --- setuptools/package_index.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index fdd0c825bf..3500c2d86f 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -854,8 +854,8 @@ def _resolve_download_filename(cls, url, tmpdir): '__downloaded__' ) - if name.endswith('.egg.zip'): - name = name[:-4] # strip the extra .zip before download + # strip any extra .zip before download + name = re.sub(r'\.egg\.zip$', '.egg', name) return os.path.join(tmpdir, name) From 8faf1d7e0ca309983252e4f21837b73ee12e960f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Apr 2025 13:41:15 -0400 Subject: [PATCH 13/16] Add news fragment. --- newsfragments/4946.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/4946.bugfix.rst diff --git a/newsfragments/4946.bugfix.rst b/newsfragments/4946.bugfix.rst new file mode 100644 index 0000000000..b9100dc313 --- /dev/null +++ b/newsfragments/4946.bugfix.rst @@ -0,0 +1 @@ +More fully sanitized the filename in PackageIndex._download. From 8e4868a036b7fae3208d16cb4e5fe6d63c3752df Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Apr 2025 14:02:36 -0400 Subject: [PATCH 14/16] =?UTF-8?q?Bump=20version:=2078.1.0=20=E2=86=92=2078?= =?UTF-8?q?.1.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- NEWS.rst | 9 +++++++++ newsfragments/4946.bugfix.rst | 1 - pyproject.toml | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) delete mode 100644 newsfragments/4946.bugfix.rst diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 16058d4c24..e949526899 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 78.1.0 +current_version = 78.1.1 commit = True tag = True diff --git a/NEWS.rst b/NEWS.rst index 304263eecd..c3718af537 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,3 +1,12 @@ +v78.1.1 +======= + +Bugfixes +-------- + +- More fully sanitized the filename in PackageIndex._download. (#4946) + + v78.1.0 ======= diff --git a/newsfragments/4946.bugfix.rst b/newsfragments/4946.bugfix.rst deleted file mode 100644 index b9100dc313..0000000000 --- a/newsfragments/4946.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -More fully sanitized the filename in PackageIndex._download. diff --git a/pyproject.toml b/pyproject.toml index 791d7013e8..08da18bbd7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ backend-path = ["."] [project] name = "setuptools" -version = "78.1.0" +version = "78.1.1" authors = [ { name = "Python Packaging Authority", email = "distutils-sig@python.org" }, ] From f89e652a79ecd4afbb71eabaf04a6709e11a4d5a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 20 Apr 2025 09:30:09 -0400 Subject: [PATCH 15/16] Removed support for the 'legacy-editable' feature. According to [the docs](https://github.com/pypa/setuptools/blob/8e4868a036b7fae3208d16cb4e5fe6d63c3752df/docs/userguide/development_mode.rst#legacy-behavior), pip no longer relies on this feature and it's been there for over two years. --- docs/userguide/development_mode.rst | 7 ---- newsfragments/917.removal.rst | 1 + setuptools/build_meta.py | 62 ++++++++++++----------------- setuptools/tests/test_build_meta.py | 24 ----------- 4 files changed, 26 insertions(+), 68 deletions(-) create mode 100644 newsfragments/917.removal.rst diff --git a/docs/userguide/development_mode.rst b/docs/userguide/development_mode.rst index 9a79b08a93..3eabe87fcb 100644 --- a/docs/userguide/development_mode.rst +++ b/docs/userguide/development_mode.rst @@ -197,13 +197,6 @@ works (still within the context of :pep:`660`). Users are encouraged to try out the new editable installation techniques and make the necessary adaptations. -.. note:: - Newer versions of ``pip`` no longer run the fallback command - ``python setup.py develop`` when the ``pyproject.toml`` file is present. - This means that setting the environment variable - ``SETUPTOOLS_ENABLE_FEATURES="legacy-editable"`` - will have no effect when installing a package with ``pip``. - How editable installations work ------------------------------- diff --git a/newsfragments/917.removal.rst b/newsfragments/917.removal.rst new file mode 100644 index 0000000000..debf9bdc3a --- /dev/null +++ b/newsfragments/917.removal.rst @@ -0,0 +1 @@ +Removed support for 'legacy-editable' installs. diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 00fa5e1f70..8f2e930c73 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -67,9 +67,6 @@ 'SetupRequirementsError', ] -SETUPTOOLS_ENABLE_FEATURES = os.getenv("SETUPTOOLS_ENABLE_FEATURES", "").lower() -LEGACY_EDITABLE = "legacy-editable" in SETUPTOOLS_ENABLE_FEATURES.replace("_", "-") - class SetupRequirementsError(BaseException): def __init__(self, specifiers) -> None: @@ -457,37 +454,30 @@ def _get_dist_info_dir(self, metadata_directory: StrPath | None) -> str | None: assert len(dist_info_candidates) <= 1 return str(dist_info_candidates[0]) if dist_info_candidates else None - if not LEGACY_EDITABLE: - # PEP660 hooks: - # build_editable - # get_requires_for_build_editable - # prepare_metadata_for_build_editable - def build_editable( - self, - wheel_directory: StrPath, - config_settings: _ConfigSettings = None, - metadata_directory: StrPath | None = None, - ): - # XXX can or should we hide our editable_wheel command normally? - info_dir = self._get_dist_info_dir(metadata_directory) - opts = ["--dist-info-dir", info_dir] if info_dir else [] - cmd = ["editable_wheel", *opts, *self._editable_args(config_settings)] - with suppress_known_deprecation(): - return self._build_with_temp_dir( - cmd, ".whl", wheel_directory, config_settings - ) + def build_editable( + self, + wheel_directory: StrPath, + config_settings: _ConfigSettings = None, + metadata_directory: StrPath | None = None, + ): + # XXX can or should we hide our editable_wheel command normally? + info_dir = self._get_dist_info_dir(metadata_directory) + opts = ["--dist-info-dir", info_dir] if info_dir else [] + cmd = ["editable_wheel", *opts, *self._editable_args(config_settings)] + with suppress_known_deprecation(): + return self._build_with_temp_dir( + cmd, ".whl", wheel_directory, config_settings + ) - def get_requires_for_build_editable( - self, config_settings: _ConfigSettings = None - ): - return self.get_requires_for_build_wheel(config_settings) + def get_requires_for_build_editable(self, config_settings: _ConfigSettings = None): + return self.get_requires_for_build_wheel(config_settings) - def prepare_metadata_for_build_editable( - self, metadata_directory: StrPath, config_settings: _ConfigSettings = None - ): - return self.prepare_metadata_for_build_wheel( - metadata_directory, config_settings - ) + def prepare_metadata_for_build_editable( + self, metadata_directory: StrPath, config_settings: _ConfigSettings = None + ): + return self.prepare_metadata_for_build_wheel( + metadata_directory, config_settings + ) class _BuildMetaLegacyBackend(_BuildMetaBackend): @@ -549,11 +539,9 @@ class _IncompatibleBdistWheel(SetuptoolsDeprecationWarning): prepare_metadata_for_build_wheel = _BACKEND.prepare_metadata_for_build_wheel build_wheel = _BACKEND.build_wheel build_sdist = _BACKEND.build_sdist - -if not LEGACY_EDITABLE: - get_requires_for_build_editable = _BACKEND.get_requires_for_build_editable - prepare_metadata_for_build_editable = _BACKEND.prepare_metadata_for_build_editable - build_editable = _BACKEND.build_editable +get_requires_for_build_editable = _BACKEND.get_requires_for_build_editable +prepare_metadata_for_build_editable = _BACKEND.prepare_metadata_for_build_editable +build_editable = _BACKEND.build_editable # The legacy backend diff --git a/setuptools/tests/test_build_meta.py b/setuptools/tests/test_build_meta.py index 624bba862e..57162fd6af 100644 --- a/setuptools/tests/test_build_meta.py +++ b/setuptools/tests/test_build_meta.py @@ -936,30 +936,6 @@ def test_sys_argv_passthrough(self, tmpdir_cwd): build_backend.build_sdist("temp") -def test_legacy_editable_install(venv, tmpdir, tmpdir_cwd): - pyproject = """ - [build-system] - requires = ["setuptools"] - build-backend = "setuptools.build_meta" - [project] - name = "myproj" - version = "42" - """ - path.build({"pyproject.toml": DALS(pyproject), "mymod.py": ""}) - - # First: sanity check - cmd = ["pip", "install", "--no-build-isolation", "-e", "."] - output = venv.run(cmd, cwd=tmpdir).lower() - assert "running setup.py develop for myproj" not in output - assert "created wheel for myproj" in output - - # Then: real test - env = {**os.environ, "SETUPTOOLS_ENABLE_FEATURES": "legacy-editable"} - cmd = ["pip", "install", "--no-build-isolation", "-e", "."] - output = venv.run(cmd, cwd=tmpdir, env=env).lower() - assert "running setup.py develop for myproj" in output - - @pytest.mark.filterwarnings("ignore::setuptools.SetuptoolsDeprecationWarning") def test_sys_exit_0_in_setuppy(monkeypatch, tmp_path): """Setuptools should be resilient to setup.py with ``sys.exit(0)`` (#3973).""" From 56962ec38bb53e1681de00dc5dc5b2e96b1b02b8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 20 Apr 2025 11:28:20 -0400 Subject: [PATCH 16/16] =?UTF-8?q?Bump=20version:=2078.1.1=20=E2=86=92=2079?= =?UTF-8?q?.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- NEWS.rst | 9 +++++++++ newsfragments/917.removal.rst | 1 - pyproject.toml | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) delete mode 100644 newsfragments/917.removal.rst diff --git a/.bumpversion.cfg b/.bumpversion.cfg index e949526899..ce3d207697 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 78.1.1 +current_version = 79.0.0 commit = True tag = True diff --git a/NEWS.rst b/NEWS.rst index c3718af537..e7f33786a3 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,3 +1,12 @@ +v79.0.0 +======= + +Deprecations and Removals +------------------------- + +- Removed support for 'legacy-editable' installs. (#917) + + v78.1.1 ======= diff --git a/newsfragments/917.removal.rst b/newsfragments/917.removal.rst deleted file mode 100644 index debf9bdc3a..0000000000 --- a/newsfragments/917.removal.rst +++ /dev/null @@ -1 +0,0 @@ -Removed support for 'legacy-editable' installs. diff --git a/pyproject.toml b/pyproject.toml index 08da18bbd7..3ba37aa59d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ backend-path = ["."] [project] name = "setuptools" -version = "78.1.1" +version = "79.0.0" authors = [ { name = "Python Packaging Authority", email = "distutils-sig@python.org" }, ]