Skip to content

Commit f1b9801

Browse files
committed
First attempt to update urllib3
1 parent e8bbdd8 commit f1b9801

1 file changed

Lines changed: 95 additions & 9 deletions

File tree

relenv/build/common/install.py

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66
from __future__ import annotations
77

8+
import base64
89
import fnmatch
910
import hashlib
1011
import io
@@ -18,6 +19,7 @@
1819
import shutil
1920
import sys
2021
import tarfile
22+
import zipfile
2123
from types import ModuleType
2224
from typing import IO, MutableMapping, Optional, Sequence, Union, TYPE_CHECKING
2325

@@ -27,6 +29,7 @@
2729
MissingDependencyError,
2830
Version,
2931
download_url,
32+
extract_archive,
3033
format_shebang,
3134
runcmd,
3235
)
@@ -246,8 +249,18 @@ def update_ensurepip(directory: pathlib.Path) -> None:
246249

247250
# Detect existing whl. Later versions of python don't include setuptools. We
248251
# only want to update whl files that python expects to be there
249-
pip_version = "25.2"
252+
pip_version = "25.3"
253+
pip_whl = f"pip-{pip_version}-py3-none-any.whl"
254+
pip_whl_path = "44/3c/d717024885424591d5376220b5e836c2d5293ce2011523c9de23ff7bf068"
255+
250256
setuptools_version = "80.9.0"
257+
setuptools_whl = f"setuptools-{setuptools_version}-py3-none-any.whl"
258+
setuptools_whl_path = "a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772"
259+
260+
urllib3_version = "2.6.2"
261+
urllib3_tarball = f"urllib3-{urllib3_version}.tar.gz"
262+
urllib3_tarball_path = "1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd"
263+
251264
update_pip = False
252265
update_setuptools = False
253266
for file in bundle_dir.glob("*.whl"):
@@ -275,11 +288,9 @@ def update_ensurepip(directory: pathlib.Path) -> None:
275288
# Download whl files and update __init__.py
276289
init_file = directory / "ensurepip" / "__init__.py"
277290
if update_pip:
278-
whl = f"pip-{pip_version}-py3-none-any.whl"
279-
whl_path = "b7/3f/945ef7ab14dc4f9d7f40288d2df998d1837ee0888ec3659c813487572faa"
280-
url = f"https://files.pythonhosted.org/packages/{whl_path}/{whl}"
291+
url = f"https://files.pythonhosted.org/packages/{pip_whl_path}/{pip_whl}"
281292
download_url(url=url, dest=bundle_dir)
282-
assert (bundle_dir / whl).exists()
293+
assert (bundle_dir / pip_whl).exists()
283294

284295
# Update __init__.py
285296
old = "^_PIP_VERSION.*"
@@ -288,11 +299,9 @@ def update_ensurepip(directory: pathlib.Path) -> None:
288299

289300
# setuptools
290301
if update_setuptools:
291-
whl = f"setuptools-{setuptools_version}-py3-none-any.whl"
292-
whl_path = "a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772"
293-
url = f"https://files.pythonhosted.org/packages/{whl_path}/{whl}"
302+
url = f"https://files.pythonhosted.org/packages/{setuptools_whl_path}/{setuptools_whl}"
294303
download_url(url=url, dest=bundle_dir)
295-
assert (bundle_dir / whl).exists()
304+
assert (bundle_dir / setuptools_whl).exists()
296305

297306
# setuptools
298307
old = "^_SETUPTOOLS_VERSION.*"
@@ -302,6 +311,83 @@ def update_ensurepip(directory: pathlib.Path) -> None:
302311
log.debug("ensurepip __init__.py contents:")
303312
log.debug(init_file.read_text())
304313

314+
# TODO: unpack the pip whl using zipfile (wheel isn't installed yet)
315+
pip_whl_extracted = bundle_dir / "pip_whl_extracted"
316+
with zipfile.ZipFile(bundle_dir / pip_whl) as whl_file:
317+
whl_file.extractall(path=pip_whl_extracted)
318+
319+
# TODO: pull down urllib3 tarball
320+
url = f"https://files.pythonhosted.org/packages/{urllib3_tarball_path}/{urllib3_tarball}"
321+
download_url(url=url, dest=bundle_dir)
322+
assert (bundle_dir / urllib3_tarball).exists()
323+
324+
# TODO: Extract the tarball
325+
urllib3_extracted = bundle_dir / "urllib3_extracted"
326+
extract_archive(to_dir=urllib3_extracted, archive=bundle_dir / urllib3_tarball)
327+
328+
# TODO: replace urllib3 in pip
329+
# Delete target urllib3
330+
urllib3_target_dir = bundle_dir / pip_whl_extracted / f"pip-{pip_version}" / "pip" / "_vendor" / "urllib3"
331+
urllib3_source_dir = urllib3_extracted / "src" / "urllib3"
332+
try:
333+
shutil.rmtree(urllib3_target_dir)
334+
log.debug("Removed urllib3 target directory: %s", urllib3_target_dir)
335+
except OSError:
336+
log.debug("Failed to remove urllib3 target directory: %s", urllib3_target_dir)
337+
338+
# Move source urllib3 to target
339+
urllib3_source_dir.rename(urllib3_target_dir)
340+
341+
# Cleanup urllib3 source and tarball
342+
shutil.rmtree(urllib3_extracted)
343+
(bundle_dir / urllib3_tarball).unlink(missing_ok=True)
344+
345+
# TODO: recompute the hashes and update dist-info\RECORD
346+
def get_record_entry(file_path, root_dir):
347+
# 1. Calculate SHA256 and Size
348+
sha256 = hashlib.sha256()
349+
size = os.path.getsize(file_path)
350+
351+
with open(file_path, 'rb') as f:
352+
while chunk := f.read(8192):
353+
sha256.update(chunk)
354+
355+
# 2. Encode to URL-safe Base64 and remove padding '='
356+
hash_base64 = base64.urlsafe_b64encode(sha256.digest()).decode('latin1').rstrip('=')
357+
358+
# 3. Create relative path for RECORD
359+
rel_path = os.path.relpath(file_path, root_dir).replace(os.sep, '/')
360+
361+
return f"{rel_path},sha256={hash_base64},{size}"
362+
363+
pip_src_dir = pip_whl_extracted / f"pip-{pip_version}"
364+
# delete existing RECORD file
365+
records_file = pip_src_dir / f"pip-{pip_version}.dist-info" / "RECORD"
366+
records_file.unlink(missing_ok=True)
367+
# create new RECORD file
368+
files_list = [f for f in pip_src_dir.rglob("*") if f.is_file()]
369+
with open(records_file, "w") as f:
370+
for file in files_list:
371+
f.write(get_record_entry(file, root_dir=pip_src_dir) + "\n")
372+
# This is the last line. It shouldn't be there because we removed the
373+
# RECORD file before we listed all files
374+
f.write(f"pip-{pip_version}.dist-info/RECORD,,")
375+
assert records_file.exists()
376+
377+
# TODO: pack the pip whl
378+
(bundle_dir / pip_whl).unlink(missing_ok=True)
379+
# We need to do this again so we include the RECORD file
380+
files_list = [f for f in pip_src_dir.rglob("*") if f.is_file()]
381+
with zipfile.ZipFile(bundle_dir / pip_whl, "w", zipfile.ZIP_DEFLATED) as whl_file:
382+
for file in files_list:
383+
arc_name = file.relative_to(pip_src_dir)
384+
whl_file.write(file, arc_name)
385+
assert (bundle_dir / pip_whl).exists()
386+
387+
# TODO: Clean up extracted pip
388+
shutil.rmtree(pip_whl_extracted)
389+
assert not pip_whl_extracted.exists()
390+
305391

306392
def install_sysdata(
307393
mod: ModuleType,

0 commit comments

Comments
 (0)