From dc6553efa5bfc567d6cbde44dd104921a589ac84 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 00:04:54 -0400 Subject: [PATCH 01/13] Use flit to build pip distributions --- .github/workflows/ci.yml | 2 +- MANIFEST.in | 34 --------- build-project/build-requirements.in | 2 +- build-project/build-requirements.txt | 16 ++-- .../html/development/architecture/anatomy.rst | 1 - pyproject.toml | 73 ++++++++++++------- 6 files changed, 56 insertions(+), 72 deletions(-) delete mode 100644 MANIFEST.in diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 815617e1c19..6d0c8a2aa41 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,7 +82,7 @@ jobs: - run: pip install nox - run: nox -s prepare-release -- 99.9 - run: nox -s build-release -- 99.9 - - run: pipx run check-manifest + - run: pipx run check-sdist vendoring: name: vendoring diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 998cb4f485e..00000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,34 +0,0 @@ -include NEWS.rst -include README.rst -include SECURITY.md -include pyproject.toml - -include build-project/build-requirements.in -include build-project/build-requirements.txt -include build-project/build-project.py -include build-project/.python-version - -include src/pip/_vendor/README.rst -include src/pip/_vendor/vendor.txt - -include docs/requirements.txt - -exclude .git-blame-ignore-revs -exclude .mailmap -exclude .readthedocs.yml -exclude .pre-commit-config.yaml -exclude .readthedocs-custom-redirects.yml -exclude noxfile.py - -recursive-include src/pip/_vendor *.pem -recursive-include src/pip/_vendor py.typed -recursive-include docs *.css *.py *.rst *.md -recursive-include docs *.dot *.png - -recursive-exclude src/pip/_vendor *.pyi - -prune .github -prune docs/build -prune news -prune tests -prune tools diff --git a/build-project/build-requirements.in b/build-project/build-requirements.in index 4bc215a28d0..07a76cea647 100644 --- a/build-project/build-requirements.in +++ b/build-project/build-requirements.in @@ -1,2 +1,2 @@ build -setuptools +flit-core diff --git a/build-project/build-requirements.txt b/build-project/build-requirements.txt index c0cf0575088..65b647daf2c 100644 --- a/build-project/build-requirements.txt +++ b/build-project/build-requirements.txt @@ -8,17 +8,15 @@ build==1.2.2.post1 \ --hash=sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5 \ --hash=sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7 # via -r build-requirements.in -packaging==24.2 \ - --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ - --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f +flit-core==3.12.0 \ + --hash=sha256:18f63100d6f94385c6ed57a72073443e1a71a4acb4339491615d0f16d6ff01b2 \ + --hash=sha256:e7a0304069ea895172e3c7bb703292e992c5d1555dd1233ab7b5621b5b69e62c + # via -r build-requirements.in +packaging==25.0 \ + --hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 \ + --hash=sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f # via build pyproject-hooks==1.2.0 \ --hash=sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8 \ --hash=sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 # via build - -# The following packages are considered to be unsafe in a requirements file: -setuptools==80.9.0 \ - --hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \ - --hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c - # via -r build-requirements.in diff --git a/docs/html/development/architecture/anatomy.rst b/docs/html/development/architecture/anatomy.rst index d5e205654ff..7a0fefbfa63 100644 --- a/docs/html/development/architecture/anatomy.rst +++ b/docs/html/development/architecture/anatomy.rst @@ -18,7 +18,6 @@ The ``README``, license, ``pyproject.toml``, and so on are in the top level. * ``AUTHORS.txt`` * ``LICENSE.txt`` -* ``MANIFEST.in`` * ``NEWS.rst`` * ``pyproject.toml`` * ``README.rst`` diff --git a/pyproject.toml b/pyproject.toml index cc420de957f..4b5e2edf33a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,5 @@ [project] dynamic = ["version"] - name = "pip" description = "The PyPA recommended tool for installing Python packages." readme = "README.rst" @@ -45,31 +44,53 @@ Source = "https://github.com/pypa/pip" Changelog = "https://pip.pypa.io/en/stable/news/" [build-system] -requires = ["setuptools>=77"] -build-backend = "setuptools.build_meta" - -[tool.setuptools] -package-dir = {"" = "src"} -include-package-data = false - -[tool.setuptools.dynamic] -version = {attr = "pip.__version__"} - -[tool.setuptools.packages.find] -where = ["src"] -exclude = ["contrib", "docs", "tests*", "tasks"] - -[tool.setuptools.package-data] -"pip" = ["py.typed"] -"pip._vendor" = ["vendor.txt"] -"pip._vendor.certifi" = ["*.pem"] -"pip._vendor.distlib" = [ - "t32.exe", - "t64.exe", - "t64-arm.exe", - "w32.exe", - "w64.exe", - "w64-arm.exe", +requires = ["flit-core >=3.8,<4"] +build-backend = "flit_core.buildapi" + +[tool.flit.module] +name = "pip" +path = "src/pip" + +[tool.flit.sdist] +include = [ + "AUTHORS.txt", + "LICENSE.txt", + "NEWS.rst", + "README.rst", + "SECURITY.md", + "pyproject.toml", + "build-project/build-requirements.in", + "build-project/build-requirements.txt", + "build-project/build-project.py", + "build-project/.python-version", + "src/pip/_vendor/README.rst", + "src/pip/_vendor/vendor.txt", + "src/pip/_vendor/**/*LICENSE*", + "src/pip/_vendor/**/*COPYING*", + "docs/requirements.txt", + "src/pip/_vendor/**/*.pem", + "src/pip/_vendor/**/py.typed", + "docs/**/*.css", + "docs/**/*.py", + "docs/**/*.rst", + "docs/**/*.md", + "docs/**/*.dot", + "docs/**/*.png", +] + +exclude = [ + ".git-blame-ignore-revs", + ".mailmap", + ".readthedocs.yml", + ".pre-commit-config.yaml", + ".readthedocs-custom-redirects.yml", + "noxfile.py", + "*.pyi", + ".github/**", + "docs/build/**", + "news/**", + "tests/**", + "tools/**", ] ###################################################################################### From 3e78a5c938525ac70330a5501ac568a4d93b364f Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 00:19:05 -0400 Subject: [PATCH 02/13] Add git-only section to check-sdist --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 4b5e2edf33a..7c8dd11a37f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -341,3 +341,10 @@ exclude_also = [ # This excludes typing-specific code, which will be validated by mypy anyway. "if TYPE_CHECKING", ] + +[tool.check-sdist] +git-only = [ + "tests/**", + "tools/**" +] +default-ignore = true From 5f97a96c09ad7c31f9c9719e8bc5cc8b9f900ec4 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 00:24:21 -0400 Subject: [PATCH 03/13] Add more ignores --- pyproject.toml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7c8dd11a37f..3afd40fb36a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -344,7 +344,10 @@ exclude_also = [ [tool.check-sdist] git-only = [ - "tests/**", - "tools/**" + "tests/**", + "tools/**", + ".gitattributes", + ".gitignore", + "news/.gitignore" ] default-ignore = true From 693145cee0871fba3a4a4d7ebf4afbd3511ecf27 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 00:35:39 -0400 Subject: [PATCH 04/13] Add flit-core to test requirements --- tests/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/requirements.txt b/tests/requirements.txt index 0568aea5178..3300520209e 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,5 +1,6 @@ cryptography freezegun +flit-core installer pytest pytest-cov From fc392d3f081edcd9217a40d0e4dcd85f9a90a5d3 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 00:41:08 -0400 Subject: [PATCH 05/13] Add flit-core to common wheels for tests --- tests/requirements-common_wheels.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/requirements-common_wheels.txt b/tests/requirements-common_wheels.txt index 31450a0e861..86ffefedf7e 100644 --- a/tests/requirements-common_wheels.txt +++ b/tests/requirements-common_wheels.txt @@ -8,6 +8,8 @@ # We pin setuptools<80 because our test suite currently # depends on setup.py develop to generate egg-link files. setuptools >= 40.8.0, != 60.6.0, <80 +# flit-core is now the build backend for pip itself +flit-core >= 3.8, < 4 wheel # As required by pytest-cov. coverage >= 4.4 From 7c0e408b457d18e5e3bf592aff65ddff943c08db Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 00:53:55 -0400 Subject: [PATCH 06/13] install flit-core for test_self_update_editable test (hack?) --- tests/functional/test_self_update.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/functional/test_self_update.py b/tests/functional/test_self_update.py index 1331a87c319..9019e89211d 100644 --- a/tests/functional/test_self_update.py +++ b/tests/functional/test_self_update.py @@ -8,6 +8,9 @@ def test_self_update_editable(script: Any, pip_src: Any) -> None: # mode, that pip can safely update itself to an editable install. # See https://github.com/pypa/pip/issues/12666 for details. + # Install flit-core (build backend) since we use --no-build-isolation + script.pip("install", "flit-core") + # Step 1. Install pip as non-editable. This is expected to succeed as # the existing pip in the environment is installed in editable mode, so # it only places a .pth file in the environment. From 3b5502f512c99eb4f7bc25cc13ca35eb08786b5e Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 11:28:08 -0400 Subject: [PATCH 07/13] Update pyproject.toml Co-authored-by: Richard Si --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3afd40fb36a..faf192f7524 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,7 @@ exclude = [ ".pre-commit-config.yaml", ".readthedocs-custom-redirects.yml", "noxfile.py", - "*.pyi", + "**/*.pyi", ".github/**", "docs/build/**", "news/**", From a4f0a005e813f3b1b85851e6c31447dcb23372ba Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 23:28:06 -0400 Subject: [PATCH 08/13] Update flit requirements and config based on feedback --- pyproject.toml | 56 ++++++++-------------------- tests/requirements-common_wheels.txt | 2 +- tests/requirements.txt | 2 +- 3 files changed, 17 insertions(+), 43 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index faf192f7524..a07b9a7890e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,53 +44,27 @@ Source = "https://github.com/pypa/pip" Changelog = "https://pip.pypa.io/en/stable/news/" [build-system] -requires = ["flit-core >=3.8,<4"] +requires = ["flit-core >=3.11,<4"] build-backend = "flit_core.buildapi" -[tool.flit.module] -name = "pip" -path = "src/pip" - [tool.flit.sdist] include = [ - "AUTHORS.txt", - "LICENSE.txt", - "NEWS.rst", - "README.rst", - "SECURITY.md", - "pyproject.toml", - "build-project/build-requirements.in", - "build-project/build-requirements.txt", - "build-project/build-project.py", - "build-project/.python-version", - "src/pip/_vendor/README.rst", - "src/pip/_vendor/vendor.txt", - "src/pip/_vendor/**/*LICENSE*", - "src/pip/_vendor/**/*COPYING*", - "docs/requirements.txt", - "src/pip/_vendor/**/*.pem", - "src/pip/_vendor/**/py.typed", - "docs/**/*.css", - "docs/**/*.py", - "docs/**/*.rst", - "docs/**/*.md", - "docs/**/*.dot", - "docs/**/*.png", + "NEWS.rst", + "SECURITY.md", + "build-project/.python-version", + "build-project/build-project.py", + "build-project/build-requirements.in", + "build-project/build-requirements.txt", + "docs/requirements.txt", + "docs/**/*.css", + "docs/**/*.dot", + "docs/**/*.md", + "docs/**/*.png", + "docs/**/*.py", + "docs/**/*.rst", ] - exclude = [ - ".git-blame-ignore-revs", - ".mailmap", - ".readthedocs.yml", - ".pre-commit-config.yaml", - ".readthedocs-custom-redirects.yml", - "noxfile.py", - "**/*.pyi", - ".github/**", - "docs/build/**", - "news/**", - "tests/**", - "tools/**", + "src/pip/_vendor/**/*.pyi", ] ###################################################################################### diff --git a/tests/requirements-common_wheels.txt b/tests/requirements-common_wheels.txt index 86ffefedf7e..48520aa7ddf 100644 --- a/tests/requirements-common_wheels.txt +++ b/tests/requirements-common_wheels.txt @@ -9,7 +9,7 @@ # depends on setup.py develop to generate egg-link files. setuptools >= 40.8.0, != 60.6.0, <80 # flit-core is now the build backend for pip itself -flit-core >= 3.8, < 4 +flit-core >= 3.11, < 4 wheel # As required by pytest-cov. coverage >= 4.4 diff --git a/tests/requirements.txt b/tests/requirements.txt index 3300520209e..44e9df057a2 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,6 +1,6 @@ cryptography freezegun -flit-core +flit-core >= 3.11, < 4 installer pytest pytest-cov From 535940ccc2dd444474876b17c32060f5c48de384 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 23:29:04 -0400 Subject: [PATCH 09/13] Remove default ignore for check-sdist --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a07b9a7890e..417f9a3e4dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -324,4 +324,3 @@ git-only = [ ".gitignore", "news/.gitignore" ] -default-ignore = true From b91d82a72d522f25e3b9ac3ab81f2f38fb768838 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 23:31:17 -0400 Subject: [PATCH 10/13] Add more git-only files to check-sdist --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 417f9a3e4dd..60b235a7678 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -320,7 +320,10 @@ exclude_also = [ git-only = [ "tests/**", "tools/**", + "news/.gitignore", ".gitattributes", ".gitignore", - "news/.gitignore" + ".git-blame-ignore-revs", + ".mailmap", + ".readthedocs-custom-redirects.yml" ] From 324e84f282ddc08cdb0d724075e7caa5f330045f Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Wed, 9 Jul 2025 23:56:34 -0400 Subject: [PATCH 11/13] Update `test_freeze_with_setuptools` test --- tests/functional/test_freeze.py | 41 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/tests/functional/test_freeze.py b/tests/functional/test_freeze.py index 0a7cedd11cb..9883beb87fd 100644 --- a/tests/functional/test_freeze.py +++ b/tests/functional/test_freeze.py @@ -99,38 +99,33 @@ def test_freeze_with_pip(script: PipTestEnvironment) -> None: def test_freeze_with_setuptools(script: PipTestEnvironment) -> None: """ - Test that pip shows setuptools only when --all is used - or _should_suppress_build_backends() returns false + Test that pip shows setuptools only when --all is used on Python < 3.12, + otherwise it should be shown in default freeze output. """ result = script.pip("freeze", "--all") assert "setuptools==" in result.stdout - (script.site_packages_path / "mock.pth").write_text("import mock\n") - - (script.site_packages_path / "mock.py").write_text( - textwrap.dedent( - """\ - import pip._internal.commands.freeze as freeze - freeze._should_suppress_build_backends = lambda: False - """ - ) - ) - + # Test the default behavior (without --all) result = script.pip("freeze") - assert "setuptools==" in result.stdout - (script.site_packages_path / "mock.py").write_text( - textwrap.dedent( - """\ - import pip._internal.commands.freeze as freeze - freeze._should_suppress_build_backends = lambda: True - """ + should_suppress = sys.version_info < (3, 12) + if should_suppress: + # setuptools should be hidden in default freeze output + assert "setuptools==" not in result.stdout, ( + f"setuptools should be suppressed in Python {sys.version_info[:2]} " + f"but was found in freeze output: {result.stdout}" + ) + else: + # setuptools should be shown in default freeze output + assert "setuptools==" in result.stdout, ( + f"setuptools should be shown in Python {sys.version_info[:2]} " + f"but was not found in freeze output: {result.stdout}" ) - ) - result = script.pip("freeze") - assert "setuptools==" not in result.stdout + # --all should always show setuptools regardless of version + result_all = script.pip("freeze", "--all") + assert "setuptools==" in result_all.stdout def test_exclude_and_normalization(script: PipTestEnvironment, tmpdir: Path) -> None: From 173d06fbd0700aa2c41fe0e529956bbbe0c25945 Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Thu, 10 Jul 2025 00:16:23 -0400 Subject: [PATCH 12/13] Add News Entry --- news/13743.feature.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 news/13743.feature.rst diff --git a/news/13743.feature.rst b/news/13743.feature.rst new file mode 100644 index 00000000000..37f7db147f8 --- /dev/null +++ b/news/13743.feature.rst @@ -0,0 +1,2 @@ +Building pip itself from source now uses flit-core instead of setuptools. +This does not affect how pip installs or builds packages you use. From 1939fa6717db3a11e6a9c0ebba81f8186189f2fb Mon Sep 17 00:00:00 2001 From: Damian Shaw Date: Thu, 10 Jul 2025 11:49:45 -0400 Subject: [PATCH 13/13] Add flit into new dependency groups --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0bb42cf47b0..8f7b03813a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ build-backend = "flit_core.buildapi" [dependency-groups] test = [ "cryptography", + "flit-core >= 3.11, < 4", "freezegun", "installer", "pytest", @@ -69,6 +70,7 @@ test = [ ] test-common-wheels = [ + "flit-core >= 3.11, < 4", # We pin setuptools<80 because our test suite currently # depends on setup.py develop to generate egg-link files. "setuptools >= 40.8.0, != 60.6.0, <80",