-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DLL load failed while importing _speedup with conda+python3.8+windows #237
Comments
Thanks for reporting! Windows binary extensions are absolutely a weak point of my expertise and I don't have a great way to test these things. Can you run Also, in that same environment could you run a few test commands? The >>> import ctypes
>>> dll_name = "bezier-b9fda8dc.dll" # or "bezier-7be4e22c.dll" in 32-bit
>>> ctypes.cdll.LoadLibrary(dll_name) # Should fail before adding `extra-dll` to search path
>>> import os
>>> os.add_dll_directory(r"E:\PPUU\lib\site-packages\bezier\extra-dll")
>>> ctypes.cdll.LoadLibrary(dll_name) # Should succeed PS: 找不到指定的模块 == Cannot find the specified module (for related searches) |
Thank you for your reply! If you want to reproduce this env, this environment.yaml will help. You can run I ran your code, the result is as follows: >>> import ctypes
>>> dll_name = "bezier-b9fda8dc.dll"
>>> ctypes.cdll.LoadLibrary(dll_name)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:\PPUU-test\lib\ctypes\__init__.py", line 451, in LoadLibrary
return self._dlltype(name)
File "E:\PPUU-test\lib\ctypes\__init__.py", line 373, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'bezier-b9fda8dc.dll' (or one of its dependencies). Try using the full path with constructor syntax.
>>> import os
>>> os.add_dll_directory(r"E:\PPUU-test\lib\site-packages\bezier\extra-dll")
<AddedDllDirectory('E:\\PPUU-test\\lib\\site-packages\\bezier\\extra-dll')>
>>> ctypes.cdll.LoadLibrary(dll_name)
<CDLL 'bezier-b9fda8dc.dll', handle 6a2c0000 at 0x2e4fa43f040> |
That's good to hear, so it seems the Python binary extension is what's causing issues. Can you try to import >>> import sys
>>> sys.path.append(r"E:\PPUU-test\lib\site-packages\bezier")
>>> import _speedup # Should fail because `bezier._speedup` depends on `bezier-b9fda8dc.dll`
>>> import os
>>> os.add_dll_directory(r"E:\PPUU-test\lib\site-packages\bezier\extra-dll") # Put `bezier-b9fda8dc.dll` on DLL load path
>>> import _speedup |
Seems that _speedup is still not loaded after >>> import sys
>>> sys.path.append(r"E:\PPUU-test\lib\site-packages\bezier")
>>> import _speedup
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: DLL load failed while importing _speedup: 找不到指定的模块。
>>> import os
>>> os.add_dll_directory(r"E:\PPUU-test\lib\site-packages\bezier\extra-dll")
<AddedDllDirectory('E:\\PPUU-test\\lib\\site-packages\\bezier\\extra-dll')>
>>> import _speedup
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: DLL load failed while importing _speedup: 找不到指定的模块。 |
OK, that confirms that
|
Thanks! That really helps. Hope you can get the root of this problem. |
Can confirm having the same problem with:
on a Windows 64-bit machine. |
Another report here as well: #208 (comment). Sorry I haven't had an opportunity to debug this yet, I don't have much Windows ability and my Windows machine is otherwise occupied. In addition to my comment above #237 (comment) about installing without binary extension speedups, here is another:
where |
it works for me, just run below code. you should modify your actual path of import ctypes
ctypes.cdll.LoadLibrary(r"C:\Users\oocarain\miniconda3\Lib\site-packages\bezier\extra-dll\bezier-b9fda8dc.dll") |
@Peterliwenxuan you need to set the |
Same issue, this works for me in Windows. |
def handle_import_error(caught_exc, name):
expected_msg = TEMPLATE.format(name)
if caught_exc.args == (expected_msg,) or caught_exc.msg.startswith('DLL load failed'):
return
raise caught_exc Add But manually My Python is 3.9 version. |
@lulucas I may consider doing that, but I'd prefer to just not distribute a library with a broken DLL (even if it's only broken on some architectures / OS versions). Unfortunately I don't have enough Windows knowledge or access to systems where this is known to fail to really make progress. |
This is my current workaround, is to search extra_dll_dir and load dll in there. import patch_bezier
import bezier
# do something # patch_bezier.py
import ctypes
import os
def _is_extra_dll(path):
"""Determine if a package path is the extra DLL on Windows.
Args:
path (importlib.metadata.PackagePath): A package path.
Returns:
bool: Indicating if this is the extra DLL on Windows.
"""
return "extra-dll" in path.parts and path.name.endswith(".dll")
def _get_extra_dll_dir(bezier_files):
"""Determine if a package path is the extra DLL on Windows.
Args:
bezier_files (List[importlib.metadata.PackagePath]): List of package
paths.
Returns:
str: The path of the matching ``extra-dll`` directory.
Raises:
ImportError: If no match can be found.
"""
for path in bezier_files:
if not _is_extra_dll(path):
continue
absolute_path = path.locate()
return str(absolute_path.parent)
raise ImportError("No DLL directory found", bezier_files)
def patch_dll():
"""Add the DLL directory to the module search path.
This will only modify path if
* on Windows
* the ``extra-dll`` directory is in package file metadata
"""
if os.name != "nt":
return
# pylint: disable=import-outside-toplevel
try:
import importlib.metadata as importlib_metadata
except ImportError: # pragma: NO COVER
import importlib_metadata
# pylint: enable=import-outside-toplevel
try:
bezier_files = importlib_metadata.files("bezier")
except importlib_metadata.PackageNotFoundError:
return
extra_dll_dir = _get_extra_dll_dir(bezier_files)
# load dll
for file in os.listdir(extra_dll_dir):
if file.endswith(".dll"):
ctypes.cdll.LoadLibrary(os.path.join(extra_dll_dir, file))
patch_dll() |
@lulucas This is an interesting wrinkle, thanks for sharing! Looks like the diff is here: bezier/src/python/bezier/__config__.py Line 97 in e6925aa
So def add_dll_directory(extra_dll_dir):
if not os.path.isdir(extra_dll_dir):
return
os.add_dll_directory(extra_dll_dir)
for path in pathlib.Path(extra_dll_dir).glob("*.dll"):
ctypes.cdll.LoadLibrary(path.resolve()) |
@lulucas Now that you have shined the light on this issue, I am starting to see some related reports: |
@lulucas Can you print out your full Python version? e.g. for me
|
I test it in two windows PCs, the result is intersting. this, works this is can not load dll. I will do more testing with it. |
The Anaconda distribution is the difference, right? |
In your patch, try to instead just do this os.environ["PATH"] += ";" + extra_dll_dir
os.add_dll_directory(extra_dll_dir) I.e. see if the pre-Python 3.8 behavior of just appending to |
Exactly, it's issus with anaconda. |
only Maybe ImportError can be appended with an new condition to cover below error in windows to fallback, or add some notices to README.md to warn this issue. import bezier
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\bezier\__init__.py", line 41, in <module>
__config__.handle_import_error(exc, "_speedup")
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\bezier\__config__.py", line 136, in handle_import_error
raise caught_exc
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\bezier\__init__.py", line 37, in <module>
import bezier._speedup # noqa: F401
ImportError: DLL load failed while importing _speedup: The specified module could not be found. def handle_import_error(caught_exc, name):
expected_msg = TEMPLATE.format(name)
if caught_exc.args == (expected_msg,) or caught_exc.msg.startswith('DLL load failed'):
return
raise caught_exc |
@lulucas Yes I'm aware, that's why I suggested modifying
|
I hope people worked this out but I am facing the same issue on windows.. Requirement already satisfied: bezier[full] in c:\users\hafiz\anaconda3\lib\site-packages (2021.2.12) Errro:: ImportError Traceback (most recent call last) File ~\anaconda3\lib\site-packages\bezier_init_.py:41, in File ~\anaconda3\lib\site-packages\bezier_config_.py:136, in handle_import_error(caught_exc, name) File ~\anaconda3\lib\site-packages\bezier_init_.py:37, in ImportError: DLL load failed while importing _speedup: The specified module could not be found. |
After I follow your aforementioned install method as below, I still got error information,
|
@rrryan2016 Thanks for reporting! The issue was fixed in #255 but unfortunately I haven't cut a release in quite some time. I hope to cut one soon but I am unfortunately quite busy. |
I built libbezier with Intel fortran compiler (classic) and encountered the same issue. It seems even if the compiler runtime libs are in PATH, python is not guaranteed to find (and load) them. import ctypes
ctypes.cdll.LoadLibrary(r'C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\redist\intel64_win\compiler\libifcoremd.dll') |
I'm going to close this in the hopes that later versions of Python / I am happy to re-open if we have new reports but it's been awhile since this initial discussion. @YomikoR for cases like yours, the library now supports |
Hi, I test bezier package with latest version (2020.5.19) under python3.8+anaconda+windows. It seems a compatible error.
The text was updated successfully, but these errors were encountered: