Skip to content

Commit 53b7382

Browse files
committed
fix(repair): dedupe wheel paths and tolerate missing files when deleting bad zips
1 parent 1fda564 commit 53b7382

1 file changed

Lines changed: 30 additions & 8 deletions

File tree

repair_wheels.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,34 @@
1717
import zipfile
1818

1919
from pathlib import Path
20+
from typing import Set
21+
from typing import Tuple
2022
from typing import Union
2123

2224
from colorama import Fore
2325

2426
from _helper_functions import print_color
2527

2628

29+
def _dedupe_wheel_paths(wheels_dir: Path) -> list[Path]:
30+
"""Collect *.whl under wheels_dir once per inode (rglob can list the same file twice via symlinks)."""
31+
wheels: list[Path] = []
32+
seen: Set[Tuple[int, int]] = set()
33+
for p in sorted(wheels_dir.rglob("*.whl")):
34+
try:
35+
if not p.is_file():
36+
continue
37+
st = p.stat()
38+
key = (st.st_dev, st.st_ino)
39+
except OSError:
40+
continue
41+
if key in seen:
42+
continue
43+
seen.add(key)
44+
wheels.append(p)
45+
return wheels
46+
47+
2748
def get_platform() -> str:
2849
return platform.system()
2950

@@ -91,7 +112,7 @@ def fix_universal2_wheel_name(wheel_path: Path, error_msg: str) -> Union[Path, s
91112
if "'arm64,x86_64'" in error_msg or "'x86_64,arm64'" in error_msg:
92113
# Missing BOTH architectures - wheel is corrupted, delete it
93114
print_color(" -> Deleting corrupted wheel (missing native binaries for all architectures)", Fore.RED)
94-
wheel_path.unlink()
115+
wheel_path.unlink(missing_ok=True)
95116
return "delete"
96117
elif "'x86_64'" in error_msg:
97118
# Missing x86_64, so it only has arm64
@@ -138,8 +159,8 @@ def main() -> None:
138159
temp_dir: Path = Path("./temp_repair")
139160
temp_dir.mkdir(exist_ok=True)
140161

141-
# Find all wheel files
142-
wheels: list[Path] = list(wheels_dir.rglob("*.whl"))
162+
# Find all wheel files (dedupe: same inode can appear twice via symlinks / layout quirks)
163+
wheels: list[Path] = _dedupe_wheel_paths(wheels_dir)
143164

144165
if not wheels:
145166
print_color(f"No wheels found in {wheels_dir} - nothing to repair", Fore.YELLOW)
@@ -190,7 +211,8 @@ def main() -> None:
190211
# PEP 427: wheels are zip files; invalid magic usually means truncated/corrupt CI artifact
191212
if not zipfile.is_zipfile(wheel):
192213
print_color(" -> Deleting file (not a valid zip / wheel archive)", Fore.RED)
193-
wheel.unlink()
214+
# missing_ok: duplicate paths or prior partial runs can leave nothing to remove
215+
wheel.unlink(missing_ok=True)
194216
deleted_count += 1
195217
continue
196218

@@ -255,7 +277,7 @@ def main() -> None:
255277
and "This does not look like a platform wheel, no ELF executable" in error_msg
256278
):
257279
print_color(" -> Deleting corrupted wheel", Fore.RED)
258-
wheel.unlink()
280+
wheel.unlink(missing_ok=True)
259281
deleted_count += 1
260282
continue
261283

@@ -302,19 +324,19 @@ def main() -> None:
302324
if repaired:
303325
# A repaired wheel was created successfully
304326
if repaired.name != wheel.name:
305-
wheel.unlink() # Remove original
327+
wheel.unlink(missing_ok=True) # Remove original
306328
final_path = wheel.parent / repaired.name
307329
repaired.rename(final_path)
308330
print_color(f" -> Replaced with repaired wheel: {repaired.name}", Fore.GREEN)
309331
else:
310332
# Name unchanged
311-
wheel.unlink()
333+
wheel.unlink(missing_ok=True)
312334
repaired.rename(wheel)
313335
final_path = wheel
314336
print_color(f" -> Repaired successfully: {repaired.name}", Fore.GREEN)
315337
if not zipfile.is_zipfile(final_path):
316338
print_color(" -> Deleting repaired output (not a valid zip archive)", Fore.RED)
317-
final_path.unlink()
339+
final_path.unlink(missing_ok=True)
318340
deleted_count += 1
319341
else:
320342
repaired_count += 1

0 commit comments

Comments
 (0)