fix(windows): fix numpy DLL loading in embedded Python distribution
- Generate numpy/_distributor_init_local.py during build so libopenblas can be located when running from the Windows installer - Add os.add_dll_directory() call at runtime as a fallback for embedded Python
This commit is contained in:
@@ -119,6 +119,22 @@ for whl in "$WHEEL_DIR"/*.whl; do
|
||||
unzip -qo "$whl" -d "$SITE_PACKAGES"
|
||||
done
|
||||
|
||||
# numpy wheels from PyPI don't include _distributor_init_local.py unless
|
||||
# patched by delvewheel. In embedded Python, os.add_dll_directory() is never
|
||||
# called, so libopenblas can't be found and numpy fails to import.
|
||||
# Generate the missing loader here instead.
|
||||
if [ -d "${SITE_PACKAGES}/numpy" ]; then
|
||||
cat > "${SITE_PACKAGES}/numpy/_distributor_init_local.py" << 'EOF'
|
||||
import os
|
||||
import sys
|
||||
if sys.platform == 'win32':
|
||||
_libs = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'numpy.libs'))
|
||||
if os.path.isdir(_libs):
|
||||
os.add_dll_directory(_libs)
|
||||
EOF
|
||||
echo "Generated numpy/_distributor_init_local.py"
|
||||
fi
|
||||
|
||||
cleanup_site_packages "$SITE_PACKAGES" "pyd" "dll"
|
||||
verify_frontend
|
||||
copy_app_files "$DIST_DIR"
|
||||
|
||||
@@ -15,6 +15,21 @@ def _load_numpy():
|
||||
global _np
|
||||
if _np is None:
|
||||
try:
|
||||
import os
|
||||
import sys
|
||||
if sys.platform == 'win32':
|
||||
# Embedded Python doesn't auto-load DLLs from numpy.libs;
|
||||
# add the directory explicitly so libopenblas can be found.
|
||||
try:
|
||||
import importlib.util
|
||||
spec = importlib.util.find_spec('numpy')
|
||||
if spec and spec.submodule_search_locations:
|
||||
numpy_dir = list(spec.submodule_search_locations)[0]
|
||||
libs_dir = os.path.join(os.path.dirname(numpy_dir), 'numpy.libs')
|
||||
if os.path.isdir(libs_dir):
|
||||
os.add_dll_directory(libs_dir)
|
||||
except Exception:
|
||||
pass
|
||||
import numpy as np
|
||||
_np = np
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user