Skip to content

Commit 2eff9f1

Browse files
authored
Fix ensurepip bundled pip upgrade for Python 3.12+ (#38765)
* Fix ensurepip bundled pip upgrade for Python 3.12+ * Fix ensurepip upgrade for Python 3.14 container images * Fix ensurepip upgrade for Python 3.12+ container images * Fix ensurepip upgrade * Add comment on upgrade_ensurepip Python 3.12+ incompatibility
1 parent 3732cff commit 2eff9f1

2 files changed

Lines changed: 76 additions & 3 deletions

File tree

sdks/python/container/Dockerfile

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ARG TARGETOS
2323
ARG TARGETARCH
2424

2525
COPY target/base_image_requirements.txt /tmp/base_image_requirements.txt
26+
COPY target/license_scripts/upgrade_bundled_pip.py /tmp/upgrade_bundled_pip.py
2627
COPY target/apache-beam.tar.gz /opt/apache/beam/tars/
2728
COPY target/launcher/${TARGETOS}_${TARGETARCH}/boot target/LICENSE target/NOTICE target/LICENSE.python /opt/apache/beam/
2829

@@ -85,14 +86,21 @@ RUN \
8586
rm -rf /root/.cache/pip && \
8687

8788
# Update ensurepip to use most recent versions of setuptools and pip. This avoids some vulnerabilities which won't be fixed on older versions of python.
88-
pip install upgrade_ensurepip; \
89-
python3 -m upgrade_ensurepip; \
89+
# upgrade_ensurepip is not maintained for Python 3.12+ (ensurepip no longer bundles setuptools).
90+
if [ "${py_version}" = "3.10" ] || [ "${py_version}" = "3.11" ]; then \
91+
pip install upgrade_ensurepip; \
92+
python3 -m upgrade_ensurepip; \
93+
else \
94+
python3 /tmp/upgrade_bundled_pip.py; \
95+
fi; \
9096
# setuptools is not bundled with ensurepip in Python 3.12+
9197
if [ "${py_version}" = "3.10" ] || [ "${py_version}" = "3.11" ]; then \
9298
find /usr/local/lib/python${py_version}/ensurepip/_bundled/setuptools-* -type f ! -name $(basename $(ls -v /usr/local/lib/python${py_version}/ensurepip/_bundled/setuptools-*-py3-none-any.whl | tail -n 1)) -delete; \
9399
fi; \
94100
find /usr/local/lib/python${py_version}/ensurepip/_bundled/pip-* -type f ! -name $(basename $(ls -v /usr/local/lib/python${py_version}/ensurepip/_bundled/pip-*-py3-none-any.whl | tail -n 1)) -delete; \
95-
pip uninstall upgrade_ensurepip -y; \
101+
if [ "${py_version}" = "3.10" ] || [ "${py_version}" = "3.11" ]; then \
102+
pip uninstall upgrade_ensurepip -y; \
103+
fi; \
96104
python3 -m ensurepip;
97105

98106
ENTRYPOINT ["/opt/apache/beam/boot"]
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
"""
19+
Upgrade the pip wheel bundled in ensurepip for Python 3.12+.
20+
21+
The script is executed within Docker after the image pip has been upgraded.
22+
upgrade_ensurepip expects setuptools to be bundled as well, but Python 3.12+
23+
only ships pip in ensurepip/_bundled.
24+
"""
25+
26+
import subprocess
27+
import sys
28+
from pathlib import Path
29+
30+
import ensurepip
31+
32+
33+
def main():
34+
ep_path = Path(ensurepip.__file__)
35+
wheel_dir = ep_path.parent / '_bundled'
36+
pip_version = subprocess.check_output(
37+
[sys.executable, '-m', 'pip', '--version'],
38+
text=True).split()[1]
39+
subprocess.check_call([
40+
sys.executable,
41+
'-m',
42+
'pip',
43+
'download',
44+
'pip=={}'.format(pip_version),
45+
'-d',
46+
str(wheel_dir),
47+
'--no-deps',
48+
])
49+
lines = ep_path.read_text().splitlines()
50+
pip_line = None
51+
for idx, line in enumerate(lines):
52+
if line.startswith('_PIP_VERSION = '):
53+
pip_line = idx
54+
break
55+
if pip_line is None:
56+
sys.exit('ensurepip _PIP_VERSION not found')
57+
org = ep_path.with_suffix('.py.org')
58+
if not org.exists():
59+
ep_path.rename(org)
60+
lines[pip_line] = '_PIP_VERSION = "{}"'.format(pip_version)
61+
ep_path.write_text('\n'.join(lines) + '\n')
62+
63+
64+
if __name__ == '__main__':
65+
main()

0 commit comments

Comments
 (0)