Created
January 2, 2025 13:23
-
-
Save dzogrim/fd7f8962981bb3d3cf9aff56637685b8 to your computer and use it in GitHub Desktop.
This script automates the detection and resolution of Python package architecture mismatches on macOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# This script automates the detection and resolution of Python package architecture mismatches on macOS. | |
# | |
# It scans for '.so' files compiled for x86_64 under all installed Python versions in '~/Library/Python', | |
# uninstalls the affected packages, and reinstalls them with ARM64 support. Additionally, | |
# it checks for dependency conflicts using pip check and resolves them by reinstalling problematic packages. | |
# This ensures compatibility with ARM-based systems, streamlining the transition from x86_64 to ARM architectures. | |
# | |
# TODO: clean-up everything and handle brew or port installations ... | |
set -o pipefail | |
echo "Starting Python package architecture check ..." | |
# Loop through all Python versions installed in "~/Library/Python" | |
for py_version in ~/Library/Python/3.*; do | |
PYTHON_BIN="$py_version/bin/python3" | |
PIP_BIN="$py_version/bin/pip3" | |
if [ -x "$PIP_BIN" ]; then | |
echo "Processing Python version: $py_version" | |
# Backup installed packages | |
$PIP_BIN list > /tmp/pip-packages-${py_version##*/}.txt | |
# Clear the pip cache | |
$PIP_BIN cache purge | |
# Upgrade pip now | |
sudo -H python3 -m pip install --upgrade pip --root-user-action=ignore | |
# Find x86_64 .so files and extract package names | |
find "$py_version/lib/python/site-packages/" -name "*.so" -exec file {} \; | \ | |
grep -v "_brotli*" | \ | |
grep -e "x86_64" | \ | |
awk -F'site-packages/' '{print $2}' | \ | |
cut -d'/' -f1 | \ | |
sort -u > /tmp/x86-packages-${py_version##*/}.txt | |
# Uninstall x86_64 packages | |
if [ -s /tmp/x86-packages-${py_version##*/}.txt ]; then | |
echo "Uninstalling x86_64 packages for $py_version ..." | |
xargs $PIP_BIN uninstall -y < /tmp/x86-packages-${py_version##*/}.txt | |
else | |
echo "No x86_64 packages found for $py_version." | |
fi | |
# Reinstall packages as arm64 | |
while read -r pkg; do | |
echo "Reinstalling $pkg for ARM64 ..." | |
ARCHFLAGS="-arch arm64" $PIP_BIN install --force-reinstall "$pkg" | |
done < /tmp/x86-packages-${py_version##*/}.txt | |
# Force some packages reinstallation | |
ARCHFLAGS="-arch arm64" $PIP_BIN install --force-reinstall \ | |
PyYAML pyOpenSSL cryptography zope.hookable zope.interface brotli MarkupSafe mediapipe | |
ARCHFLAGS="-arch arm64" $PIP_BIN install zipp cffi --upgrade | |
# Check for dependency conflicts | |
$PIP_BIN check | awk '{print $1}' | sort -u > /tmp/pb_packages-${py_version##*/}.txt | |
if [ -s /tmp/pb_packages-${py_version##*/}.txt ]; then | |
echo "Fixing dependency conflicts for $py_version ..." | |
# Uninstall conflicting packages | |
xargs sudo $PIP_BIN uninstall --root-user-action=ignore -y < /tmp/pb_packages-${py_version##*/}.txt | |
# Reinstall them | |
while read -r pkg; do | |
ARCHFLAGS="-arch arm64" $PIP_BIN install --force-reinstall "$pkg" | |
done < /tmp/pb_packages-${py_version##*/}.txt | |
fi | |
# Clear the pip cache | |
$PIP_BIN cache purge | |
rm -rf ~/Library/Caches/pip | |
echo "Python version $py_version processed." | |
else | |
echo "No pip found for $py_version, skipping ..." | |
fi | |
done | |
echo "All Python versions processed successfully." | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment