Skip to content

Commit ab4be44

Browse files
Backport PR #52556 on branch 2.0.x (BLD: Add DLL hashes to RECORD) (#52641)
Backport PR #52556: BLD: Add DLL hashes to RECORD Co-authored-by: Thomas Li <[email protected]>
1 parent 89846ee commit ab4be44

File tree

2 files changed

+47
-32
lines changed

2 files changed

+47
-32
lines changed

ci/fix_wheels.py

+35-32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
"""
2+
This file "repairs" our Windows wheels by copying the necessary DLLs for pandas to run
3+
on a barebones Windows installation() into the wheel.
4+
5+
NOTE: The paths for the DLLs are hard-coded to the location of the Visual Studio
6+
redistributables
7+
"""
18
import os
29
import shutil
10+
import subprocess
11+
from subprocess import CalledProcessError
312
import sys
413
import zipfile
514

@@ -18,41 +27,35 @@
1827
raise ValueError(
1928
"User must pass the path to the wheel and the destination directory."
2029
)
21-
# Wheels are zip files
2230
if not os.path.isdir(dest_dir):
2331
print(f"Created directory {dest_dir}")
2432
os.mkdir(dest_dir)
25-
shutil.copy(wheel_path, dest_dir) # Remember to delete if process fails
33+
2634
wheel_name = os.path.basename(wheel_path)
2735
success = True
28-
exception = None
29-
repaired_wheel_path = os.path.join(dest_dir, wheel_name)
30-
with zipfile.ZipFile(repaired_wheel_path, "a") as zipf:
31-
try:
32-
# TODO: figure out how licensing works for the redistributables
33-
base_redist_dir = (
34-
f"C:/Program Files (x86)/Microsoft Visual Studio/2019/"
35-
f"Enterprise/VC/Redist/MSVC/14.29.30133/{PYTHON_ARCH}/"
36-
f"Microsoft.VC142.CRT/"
37-
)
38-
zipf.write(
39-
os.path.join(base_redist_dir, "msvcp140.dll"),
40-
"pandas/_libs/window/msvcp140.dll",
41-
)
42-
zipf.write(
43-
os.path.join(base_redist_dir, "concrt140.dll"),
44-
"pandas/_libs/window/concrt140.dll",
45-
)
46-
if not is_32:
47-
zipf.write(
48-
os.path.join(base_redist_dir, "vcruntime140_1.dll"),
49-
"pandas/_libs/window/vcruntime140_1.dll",
50-
)
51-
except Exception as e:
52-
success = False
53-
exception = e
5436

55-
if not success:
56-
os.remove(repaired_wheel_path)
57-
raise exception
58-
print(f"Successfully repaired wheel was written to {repaired_wheel_path}")
37+
try:
38+
# Use the wheel CLI for zipping up the wheel since the CLI will
39+
# take care of rebuilding the hashes found in the record file
40+
tmp_dir = os.path.join(dest_dir, "tmp")
41+
with zipfile.ZipFile(wheel_path, "r") as f:
42+
# Extracting all the members of the zip
43+
# into a specific location.
44+
f.extractall(path=tmp_dir)
45+
base_redist_dir = (
46+
f"C:/Program Files (x86)/Microsoft Visual Studio/2019/"
47+
f"Enterprise/VC/Redist/MSVC/14.29.30133/{PYTHON_ARCH}/"
48+
f"Microsoft.VC142.CRT/"
49+
)
50+
required_dlls = ["msvcp140.dll", "concrt140.dll"]
51+
if not is_32:
52+
required_dlls += ["vcruntime140_1.dll"]
53+
dest_dll_dir = os.path.join(tmp_dir, "pandas/_libs/window")
54+
for dll in required_dlls:
55+
src = os.path.join(base_redist_dir, dll)
56+
shutil.copy(src, dest_dll_dir)
57+
subprocess.run(["wheel", "pack", tmp_dir, "-d", dest_dir], check=True)
58+
except CalledProcessError:
59+
print("Failed to add DLLS to wheel.")
60+
sys.exit(1)
61+
print("Successfully repaired wheel")

ci/test_wheels.py

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import shutil
44
import subprocess
5+
from subprocess import CalledProcessError
56
import sys
67

78
if os.name == "nt":
@@ -15,6 +16,17 @@
1516
wheel_path = None
1617
print(f"IS_32_BIT is {is_32_bit}")
1718
print(f"Path to built wheel is {wheel_path}")
19+
20+
print("Verifying file hashes in wheel RECORD file")
21+
try:
22+
tmp_dir = "tmp"
23+
subprocess.run(["wheel", "unpack", wheel_path, "-d", tmp_dir], check=True)
24+
except CalledProcessError:
25+
print("wheel RECORD file hash verification failed.")
26+
sys.exit(1)
27+
finally:
28+
shutil.rmtree(tmp_dir)
29+
1830
if is_32_bit:
1931
sys.exit(0) # No way to test Windows 32-bit(no docker image)
2032
if wheel_path is None:

0 commit comments

Comments
 (0)