Skip to content
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

libadalang test runner on Windows with Python3.8+ cannot find dlls #579

Closed
LordAro opened this issue Nov 10, 2021 · 4 comments
Closed

libadalang test runner on Windows with Python3.8+ cannot find dlls #579

LordAro opened this issue Nov 10, 2021 · 4 comments

Comments

@LordAro
Copy link
Contributor

LordAro commented Nov 10, 2021

Seems that Python changed how it handles dll dependencies in 3.8, and now extra paths need to be added explicitly:
https://docs.python.org/3/library/os.html#os.add_dll_directory

Currently it fails with a message something along the lines of:

Traceback (most recent call last):
  File "C:\libadalang\tmp\name_resolution__S709-005\test.py", line 1, in <module>
    import libadalang as lal
  File "C:\libadalang\build\python\libadalang\__init__.py", line 94, in <module>
    _c_lib = ctypes.cdll.LoadLibrary(_c_lib_path)
  File "C:\Python310\lib\ctypes\__init__.py", line 452, in LoadLibrary
    return self._dlltype(name)
  File "C:\Python310\lib\ctypes\__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'libadalang.dll' (or one of its dependencies). Try using the full path with constructor syntax.

As a cheap and nasty hack, the following in module_py.mako just above the LoadLibrary call seems to work, but could probably be improved:

for path in os.environ['PATH'].split(';'):
    if os.path.exists(path):
        os.add_dll_directory(path)

_c_lib = ctypes.cdll.LoadLibrary(_c_lib_path)

@LordAro LordAro changed the title libadalang est runner on Windows with Python3.8+ cannot find dlls libadalang test runner on Windows with Python3.8+ cannot find dlls Nov 10, 2021
@pmderodat
Copy link
Member

It seems that we will indeed need to do something similar. We’ll take care of it, thank you for bringing this to our attention!

@LordAro
Copy link
Contributor Author

LordAro commented May 17, 2022

Additional find - mypy 0.800 used by the langkit tests is too old for os.add_dll_directory. Looks like 0.900 should be sufficient has a new enough version of os.pyi, though it didn't seem to fix the error for me, and I got other errors (with 0.950)

langkit\utils\memoization.py:21: error: Incompatible types in assignment (expression has type "Optional[Any]", variable has type "List[Dict[Any, Any]]")
contrib\python\build\python\libpythonlang\__init__.py:72: error: Module has no attribute "add_dll_directory"
contrib\lkt\build\python\liblktlang\__init__.py:72: error: Module has no attribute "add_dll_directory"
langkit\auto_properties_dsl.py:6: error: Library stubs not installed for "docutils.parsers.rst" (or incompatible with Python 3.7)
langkit\auto_properties_dsl.py:6: note: Hint: "python3 -m pip install types-docutils"
langkit\auto_properties_dsl.py:6: note: (or run "mypy --install-types" to install all missing stub packages)
langkit\auto_properties_dsl.py:6: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
langkit\auto_properties_dsl.py:6: error: Library stubs not installed for "docutils" (or incompatible with Python 3.7)
langkit\auto_properties_dsl.py:6: error: Library stubs not installed for "docutils.parsers" (or incompatible with Python 3.7)
langkit\auto_properties_dsl.py:7: error: Library stubs not installed for "docutils.statemachine" (or incompatible with Python 3.7)
langkit\libmanage.py:690: error: Incompatible types in assignment (expression has type "Callable[[Type[BaseException], BaseException, TracebackType], Any]", variable has type "Callable[[Type[BaseException], BaseException, Optional[TracebackType]], Any]")

@pmderodat
Copy link
Member

Hello! We are unsure about the best course of action for this issue.

For the moment we think that making the Python bindings call os.add_dll_directory themselves feels to go against the design of this new mechanism. Our understanding of this situation is that it would be up to the “application packager” to do this, so whatever uses the Langkit-generated library.

With this in mind, our conclusion so far would be that there is nothing to do in Langkit.

@pmderodat
Copy link
Member

Hello,

Some time ago, we introduced a --generate-auto-dll-dirs to manage.py generate|make commands (62b8245) so that the generated code for Python bindings do the hack that you mentionned in your first message. We kept this behavior optional and disabled by default because we feel this defeats the purpose of Python’s 3.8 DLL lookup mechanism, so we likely won’t be able to do much more…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants