Skip to content

Commit d4819c5

Browse files
committed
Update pip from 25.2 to 25.3
Changelog: https://pip.pypa.io/en/stable/news/#v25-3 Additionally, we now no longer install the `wheel` package when using pip with Python 3.12 and older, since: - With modern setuptools, it's no longer necessary to manually install wheel, since setuptools will trigger its installation if needed. - As of pip 25.3, pip prepares/builds dependencies inside an isolated ephemeral build environment (~venv) that means even if wheel is installed globally, it won't be used anyway. - The Python CNB (and much of the rest of the Python ecosystem) doesn't install wheel globally any more either. This doesn't affect apps using either a different package manager, or that are using pip with Python 3.13 or newer, since we already didn't install the wheel package in those environments. GUS-W-17605676. GUS-W-20804745.
1 parent 76f07d9 commit d4819c5

File tree

10 files changed

+27
-47
lines changed

10 files changed

+27
-47
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## [Unreleased]
44

5+
- Updated pip from 25.2 to 25.3. ([#2008](https://github.com/heroku/heroku-buildpack-python/pull/2008))
6+
- Stopped installing wheel when using pip with Python 3.12 and older. ([#2008](https://github.com/heroku/heroku-buildpack-python/pull/2008))
57

68
## [v327] - 2026-01-07
79

lib/pip.sh

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ set -euo pipefail
66

77
PIP_VERSION=$(utils::get_requirement_version 'pip')
88
SETUPTOOLS_VERSION=$(utils::get_requirement_version 'setuptools')
9-
WHEEL_VERSION=$(utils::get_requirement_version 'wheel')
109

1110
function pip::install_pip() {
1211
local python_home="${1}"
@@ -21,21 +20,17 @@ function pip::install_pip() {
2120
)
2221
local packages_display_text="pip ${PIP_VERSION}"
2322

24-
# We only install setuptools and wheel on Python 3.12 and older, since:
25-
# - If either is not installed, pip will automatically install them into an isolated build
26-
# environment if needed when installing packages from an sdist. This means that for
27-
# all packages that correctly declare their metadata, it's no longer necessary to have
28-
# them installed.
23+
# We only install setuptools on Python 3.12 and older, since:
24+
# - pip now uses isolated build environments into which it installed setuptools and wheel
25+
# if needed when installing packages from an sdist.
2926
# - Most of the Python ecosystem has stopped installing them for Python 3.12+ already.
3027
# See the Python CNB's removal for more details: https://github.com/heroku/buildpacks-python/pull/243
3128
if [[ "${python_major_version}" == +(3.10|3.11|3.12) ]]; then
3229
build_data::set_string "setuptools_version" "${SETUPTOOLS_VERSION}"
33-
build_data::set_string "wheel_version" "${WHEEL_VERSION}"
3430
packages_to_install+=(
3531
"setuptools==${SETUPTOOLS_VERSION}"
36-
"wheel==${WHEEL_VERSION}"
3732
)
38-
packages_display_text+=", setuptools ${SETUPTOOLS_VERSION} and wheel ${WHEEL_VERSION}"
33+
packages_display_text+=" and setuptools ${SETUPTOOLS_VERSION}"
3934
fi
4035

4136
# Note: We still perform this install step even if the cache was reused, since we have no guarantee

requirements/pip.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
pip==25.2
1+
pip==25.3

requirements/wheel.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
# Note: This test intentionally uses Python 3.12, so that we test *.egg-link
2-
# path rewriting using older globally installed setuptools.
3-
3.12
1+
3.14

spec/fixtures/pip_editable/bin/test-entrypoints.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ set -euo pipefail
44

55
cd .heroku/python/lib/python*/site-packages/
66

7-
# List any path like strings in the .egg-link, .pth, and finder files in site-packages.
8-
grep --extended-regexp --only-matching -- '/\S+' *.egg-link *.pth __editable___*_finder.py | sort
7+
# List any path like strings in the .pth and finder files in site-packages.
8+
grep --extended-regexp --only-matching -- '/\S+' *.pth __editable___*_finder.py | sort
99
echo
1010

1111
echo -n "Running entrypoint for the pyproject.toml-based local package: "

spec/hatchet/pip_spec.rb

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -163,34 +163,27 @@
163163
end
164164
end
165165

166-
# This test intentionally uses Python 3.12, so that we test rewriting using older globally installed
167-
# setuptools (which causes .egg-link files to be created too). The Pipenv and Poetry equivalents of
168-
# this test covers the PEP-517/518 setuptools case.
169166
context 'when requirements.txt contains editable requirements (both VCS and local package)' do
170167
let(:buildpacks) { [:default, 'heroku-community/inline'] }
171168
let(:app) { Hatchet::Runner.new('spec/fixtures/pip_editable', buildpacks:) }
172169

173-
it 'rewrites .pth, .egg-link and finder paths correctly for hooks, later buildpacks, runtime and cached builds' do
170+
it 'rewrites .pth and finder paths correctly for hooks, later buildpacks, runtime and cached builds' do
174171
app.deploy do |app|
175172
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX, Regexp::MULTILINE))
176173
remote: -----> Running bin/post_compile hook
177-
remote: easy-install.pth:/app/.heroku/python/src/gunicorn
178-
remote: easy-install.pth:/tmp/build_.+/packages/local_package_setup_py
174+
remote: __editable___gunicorn_20_1_0_finder.py:/app/.heroku/python/src/gunicorn/gunicorn'}
179175
remote: __editable___local_package_pyproject_toml_0_0_1_finder.py:/tmp/build_.+/packages/local_package_pyproject_toml/local_package_pyproject_toml'}
180-
remote: gunicorn.egg-link:/app/.heroku/python/src/gunicorn
181-
remote: local-package-setup-py.egg-link:/tmp/build_.+/packages/local_package_setup_py
176+
remote: __editable___local_package_setup_py_0_0_1_finder.py:/tmp/build_.+/packages/local_package_setup_py/local_package_setup_py'}
182177
remote:
183178
remote: Running entrypoint for the pyproject.toml-based local package: Hello from pyproject.toml!
184179
remote: Running entrypoint for the setup.py-based local package: Hello from setup.py!
185180
remote: Running entrypoint for the VCS package: gunicorn \\(version 20.1.0\\)
186181
remote: -----> Saving cache
187182
.+
188183
remote: -----> Inline app detected
189-
remote: easy-install.pth:/app/.heroku/python/src/gunicorn
190-
remote: easy-install.pth:/tmp/build_.+/packages/local_package_setup_py
184+
remote: __editable___gunicorn_20_1_0_finder.py:/app/.heroku/python/src/gunicorn/gunicorn'}
191185
remote: __editable___local_package_pyproject_toml_0_0_1_finder.py:/tmp/build_.+/packages/local_package_pyproject_toml/local_package_pyproject_toml'}
192-
remote: gunicorn.egg-link:/app/.heroku/python/src/gunicorn
193-
remote: local-package-setup-py.egg-link:/tmp/build_.+/packages/local_package_setup_py
186+
remote: __editable___local_package_setup_py_0_0_1_finder.py:/tmp/build_.+/packages/local_package_setup_py/local_package_setup_py'}
194187
remote:
195188
remote: Running entrypoint for the pyproject.toml-based local package: Hello from pyproject.toml!
196189
remote: Running entrypoint for the setup.py-based local package: Hello from setup.py!
@@ -199,11 +192,9 @@
199192

200193
# Test rewritten paths work at runtime.
201194
expect(app.run('bin/test-entrypoints.sh')).to include(<<~OUTPUT)
202-
easy-install.pth:/app/.heroku/python/src/gunicorn
203-
easy-install.pth:/app/packages/local_package_setup_py
195+
__editable___gunicorn_20_1_0_finder.py:/app/.heroku/python/src/gunicorn/gunicorn'}
204196
__editable___local_package_pyproject_toml_0_0_1_finder.py:/app/packages/local_package_pyproject_toml/local_package_pyproject_toml'}
205-
gunicorn.egg-link:/app/.heroku/python/src/gunicorn
206-
local-package-setup-py.egg-link:/app/packages/local_package_setup_py
197+
__editable___local_package_setup_py_0_0_1_finder.py:/app/packages/local_package_setup_py/local_package_setup_py'}
207198
208199
Running entrypoint for the pyproject.toml-based local package: Hello from pyproject.toml!
209200
Running entrypoint for the setup.py-based local package: Hello from setup.py!
@@ -215,23 +206,19 @@
215206
app.push!
216207
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX, Regexp::MULTILINE))
217208
remote: -----> Running bin/post_compile hook
218-
remote: easy-install.pth:/app/.heroku/python/src/gunicorn
219-
remote: easy-install.pth:/tmp/build_.+/packages/local_package_setup_py
209+
remote: __editable___gunicorn_20_1_0_finder.py:/app/.heroku/python/src/gunicorn/gunicorn'}
220210
remote: __editable___local_package_pyproject_toml_0_0_1_finder.py:/tmp/build_.+/packages/local_package_pyproject_toml/local_package_pyproject_toml'}
221-
remote: gunicorn.egg-link:/app/.heroku/python/src/gunicorn
222-
remote: local-package-setup-py.egg-link:/tmp/build_.+/packages/local_package_setup_py
211+
remote: __editable___local_package_setup_py_0_0_1_finder.py:/tmp/build_.+/packages/local_package_setup_py/local_package_setup_py'}
223212
remote:
224213
remote: Running entrypoint for the pyproject.toml-based local package: Hello from pyproject.toml!
225214
remote: Running entrypoint for the setup.py-based local package: Hello from setup.py!
226215
remote: Running entrypoint for the VCS package: gunicorn \\(version 20.1.0\\)
227216
remote: -----> Saving cache
228217
.+
229218
remote: -----> Inline app detected
230-
remote: easy-install.pth:/app/.heroku/python/src/gunicorn
231-
remote: easy-install.pth:/tmp/build_.+/packages/local_package_setup_py
219+
remote: __editable___gunicorn_20_1_0_finder.py:/app/.heroku/python/src/gunicorn/gunicorn'}
232220
remote: __editable___local_package_pyproject_toml_0_0_1_finder.py:/tmp/build_.+/packages/local_package_pyproject_toml/local_package_pyproject_toml'}
233-
remote: gunicorn.egg-link:/app/.heroku/python/src/gunicorn
234-
remote: local-package-setup-py.egg-link:/tmp/build_.+/packages/local_package_setup_py
221+
remote: __editable___local_package_setup_py_0_0_1_finder.py:/tmp/build_.+/packages/local_package_setup_py/local_package_setup_py'}
235222
remote:
236223
remote: Running entrypoint for the pyproject.toml-based local package: Hello from pyproject.toml!
237224
remote: Running entrypoint for the setup.py-based local package: Hello from setup.py!
@@ -318,7 +305,7 @@
318305
remote: ! patch version automatically and prevent this warning.
319306
remote:
320307
remote: -----> Installing Python 3.10.0
321-
remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION}
308+
remote: -----> Installing pip #{PIP_VERSION} and setuptools #{SETUPTOOLS_VERSION}
322309
remote: -----> Installing dependencies using 'pip install -r requirements.txt'
323310
remote: Collecting typing-extensions==4.15.0 (from -r requirements.txt (line 2))
324311
remote: Downloading typing_extensions-4.15.0-py3-none-any.whl.metadata (3.3 kB)
@@ -378,7 +365,7 @@
378365
it 'outputs instructions for how to resolve the build failure' do
379366
app.deploy do |app|
380367
expect(clean_output(app.output)).to include(<<~OUTPUT)
381-
remote: note: This error originates from a subprocess, and is likely not a problem with pip.
368+
remote: ERROR: Failed to build 'GDAL' when getting requirements to build wheel
382369
remote:
383370
remote: ! Error: Package installation failed since the GDAL library wasn't found.
384371
remote: !

spec/hatchet/python_version_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
remote: -----> Python app detected
1111
remote: -----> Using Python #{requested_version} specified in .python-version
1212
remote: -----> Installing Python #{resolved_version}
13-
remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION}
13+
remote: -----> Installing pip #{PIP_VERSION} and setuptools #{SETUPTOOLS_VERSION}
1414
remote: -----> Installing dependencies using 'pip install -r requirements.txt'
1515
remote: Collecting typing-extensions==4.15.0 (from -r requirements.txt (line 2))
1616
OUTPUT
@@ -152,7 +152,7 @@
152152
remote: - The pip version has changed from 24.0 to #{PIP_VERSION}
153153
remote: - The legacy SQLite3 headers and CLI binary need to be uninstalled
154154
remote: -----> Installing Python #{LATEST_PYTHON_3_12}
155-
remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION}
155+
remote: -----> Installing pip #{PIP_VERSION} and setuptools #{SETUPTOOLS_VERSION}
156156
OUTPUT
157157
expect(app.run('python -V')).to eq("Python #{LATEST_PYTHON_3_12}\n")
158158
expect($CHILD_STATUS.exitstatus).to eq(0)
@@ -274,7 +274,7 @@
274274
remote: ! https://devcenter.heroku.com/articles/python-support#supported-python-versions
275275
remote:
276276
remote: -----> Installing Python #{LATEST_PYTHON_3_10}
277-
remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION}
277+
remote: -----> Installing pip #{PIP_VERSION} and setuptools #{SETUPTOOLS_VERSION}
278278
remote: -----> Installing dependencies using 'pip install -r requirements.txt'
279279
remote: Collecting typing-extensions==4.15.0 (from -r requirements.txt (line 2))
280280
OUTPUT

spec/hatchet/stack_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
remote: - The buildpack cache format has changed
7070
remote: - The legacy SQLite3 headers and CLI binary need to be uninstalled
7171
remote: -----> Installing Python #{LATEST_PYTHON_3_12}
72-
remote: -----> Installing pip #{PIP_VERSION}, setuptools #{SETUPTOOLS_VERSION} and wheel #{WHEEL_VERSION}
72+
remote: -----> Installing pip #{PIP_VERSION} and setuptools #{SETUPTOOLS_VERSION}
7373
remote: -----> Installing dependencies using 'pip install -r requirements.txt'
7474
remote: Collecting typing-extensions==4.15.0 (from -r requirements.txt (line 2))
7575
OUTPUT

spec/spec_helper.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ def get_requirement_version(package_name)
2929

3030
PIP_VERSION = get_requirement_version('pip')
3131
SETUPTOOLS_VERSION = get_requirement_version('setuptools')
32-
WHEEL_VERSION = get_requirement_version('wheel')
3332
PIPENV_VERSION = get_requirement_version('pipenv')
3433
POETRY_VERSION = get_requirement_version('poetry')
3534
UV_VERSION = get_requirement_version('uv')

0 commit comments

Comments
 (0)