Skip to content

Commit

Permalink
Backport PR #52556 on branch 2.0.x (BLD: Add DLL hashes to RECORD) (#…
Browse files Browse the repository at this point in the history
…52641)

Backport PR #52556: BLD: Add DLL hashes to RECORD

Co-authored-by: Thomas Li <47963215+lithomas1@users.noreply.github.com>
  • Loading branch information
meeseeksmachine and lithomas1 committed Apr 13, 2023
1 parent 89846ee commit ab4be44
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 32 deletions.
67 changes: 35 additions & 32 deletions ci/fix_wheels.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
"""
This file "repairs" our Windows wheels by copying the necessary DLLs for pandas to run
on a barebones Windows installation() into the wheel.
NOTE: The paths for the DLLs are hard-coded to the location of the Visual Studio
redistributables
"""
import os
import shutil
import subprocess
from subprocess import CalledProcessError
import sys
import zipfile

Expand All @@ -18,41 +27,35 @@
raise ValueError(
"User must pass the path to the wheel and the destination directory."
)
# Wheels are zip files
if not os.path.isdir(dest_dir):
print(f"Created directory {dest_dir}")
os.mkdir(dest_dir)
shutil.copy(wheel_path, dest_dir) # Remember to delete if process fails

wheel_name = os.path.basename(wheel_path)
success = True
exception = None
repaired_wheel_path = os.path.join(dest_dir, wheel_name)
with zipfile.ZipFile(repaired_wheel_path, "a") as zipf:
try:
# TODO: figure out how licensing works for the redistributables
base_redist_dir = (
f"C:/Program Files (x86)/Microsoft Visual Studio/2019/"
f"Enterprise/VC/Redist/MSVC/14.29.30133/{PYTHON_ARCH}/"
f"Microsoft.VC142.CRT/"
)
zipf.write(
os.path.join(base_redist_dir, "msvcp140.dll"),
"pandas/_libs/window/msvcp140.dll",
)
zipf.write(
os.path.join(base_redist_dir, "concrt140.dll"),
"pandas/_libs/window/concrt140.dll",
)
if not is_32:
zipf.write(
os.path.join(base_redist_dir, "vcruntime140_1.dll"),
"pandas/_libs/window/vcruntime140_1.dll",
)
except Exception as e:
success = False
exception = e

if not success:
os.remove(repaired_wheel_path)
raise exception
print(f"Successfully repaired wheel was written to {repaired_wheel_path}")
try:
# Use the wheel CLI for zipping up the wheel since the CLI will
# take care of rebuilding the hashes found in the record file
tmp_dir = os.path.join(dest_dir, "tmp")
with zipfile.ZipFile(wheel_path, "r") as f:
# Extracting all the members of the zip
# into a specific location.
f.extractall(path=tmp_dir)
base_redist_dir = (
f"C:/Program Files (x86)/Microsoft Visual Studio/2019/"
f"Enterprise/VC/Redist/MSVC/14.29.30133/{PYTHON_ARCH}/"
f"Microsoft.VC142.CRT/"
)
required_dlls = ["msvcp140.dll", "concrt140.dll"]
if not is_32:
required_dlls += ["vcruntime140_1.dll"]
dest_dll_dir = os.path.join(tmp_dir, "pandas/_libs/window")
for dll in required_dlls:
src = os.path.join(base_redist_dir, dll)
shutil.copy(src, dest_dll_dir)
subprocess.run(["wheel", "pack", tmp_dir, "-d", dest_dir], check=True)
except CalledProcessError:
print("Failed to add DLLS to wheel.")
sys.exit(1)
print("Successfully repaired wheel")
12 changes: 12 additions & 0 deletions ci/test_wheels.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import shutil
import subprocess
from subprocess import CalledProcessError
import sys

if os.name == "nt":
Expand All @@ -15,6 +16,17 @@
wheel_path = None
print(f"IS_32_BIT is {is_32_bit}")
print(f"Path to built wheel is {wheel_path}")

print("Verifying file hashes in wheel RECORD file")
try:
tmp_dir = "tmp"
subprocess.run(["wheel", "unpack", wheel_path, "-d", tmp_dir], check=True)
except CalledProcessError:
print("wheel RECORD file hash verification failed.")
sys.exit(1)
finally:
shutil.rmtree(tmp_dir)

if is_32_bit:
sys.exit(0) # No way to test Windows 32-bit(no docker image)
if wheel_path is None:
Expand Down

0 comments on commit ab4be44

Please sign in to comment.