Skip to content

DLL load failure on Windows+py3.13 only (everything else works, including Windows+py3.{10,11,12}) #2378

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

Open
joaospinto opened this issue May 2, 2025 · 5 comments

Comments

@joaospinto
Copy link

joaospinto commented May 2, 2025

Description

Any idea on what could be causing this?

  =================================== ERRORS ====================================
  __________________ ERROR collecting tests/test_simple_nlp.py __________________
  ImportError while importing test module 'D:\a\sip_python\sip_python\tests\test_simple_nlp.py'.
  Hint: make sure your test modules/packages have valid Python names.
  Traceback:
  ..\..\..\..\pypa\cibuildwheel\Cache\nuget-cpython\python.3.13.2\tools\Lib\importlib\__init__.py:88: in import_module
      return _bootstrap._gcd_import(name[level:], package, level)
  D:\a\sip_python\sip_python\tests\test_simple_nlp.py:1: in <module>
      from sip_python import (
  ..\venv-test\Lib\site-packages\sip_python\__init__.py:12: in <module>
      from .sip_python_ext import *
  E   ImportError: DLL load failed while importing sip_python_ext: The specified module could not be found.
  __________________ ERROR collecting tests/test_simple_qp.py ___________________
  ImportError while importing test module 'D:\a\sip_python\sip_python\tests\test_simple_qp.py'.
  Hint: make sure your test modules/packages have valid Python names.
  Traceback:
  ..\..\..\..\pypa\cibuildwheel\Cache\nuget-cpython\python.3.13.2\tools\Lib\importlib\__init__.py:88: in import_module
      return _bootstrap._gcd_import(name[level:], package, level)
  D:\a\sip_python\sip_python\tests\test_simple_qp.py:1: in <module>
      from sip_python import (
  ..\venv-test\Lib\site-packages\sip_python\__init__.py:12: in <module>
      from .sip_python_ext import *
  E   ImportError: DLL load failed while importing sip_python_ext: The specified module could not be found.
  =========================== short test summary info ===========================
  ERROR D:\a\sip_python\sip_python\tests\test_simple_nlp.py
  ERROR D:\a\sip_python\sip_python\tests\test_simple_qp.py
  !!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!
  ============================== 2 errors in 0.31s ==============================

Interestingly, the build step in this case (and only this case) is skipped, due to:

Found previously built wheel sip_python-0.0.1-cp312-abi3-win_amd64.whl, that's compatible with cp313-win_amd64. Skipping build step...

I couldn't immediately find any relevant pointers/information, so I figured it might be a good idea to post here.
Thanks!

Build log

https://github.com/joaospinto/sip_python/actions/runs/14787739762/job/41519089621

CI config

https://github.com/joaospinto/sip_python/blob/main/.github/workflows/wheels.yml

@henryiii
Copy link
Contributor

henryiii commented May 6, 2025

Looks like a collision between an extension claiming it supports ABI 3, but not providing the correct extension. What's the binary file extension inside the 3.12 wheel?

Though it seems like it does know there's a binary file here, so maybe that's not it.

@Doekin
Copy link

Doekin commented May 7, 2025

I encountered a similar issue, albeit with a different error message:

ImportError: DLL load failed while importing zxingcpp: %1 is not a valid Win32 application.

In my case, 32-bit Python 3.13 failed to import an extension built with the nanobind binding library, packaged as a cp312-abi3-win32 wheel. The error log looked like this:

============================= test session starts =============================
platform win32 -- Python 3.13.3, pytest-8.3.5, pluggy-1.5.0
rootdir: D:\a\zxing-cpp\zxing-cpp\wrappers\python
configfile: pyproject.toml
collected 0 items / 1 error

=================================== ERRORS ====================================
__________________________ ERROR collecting test.py ___________________________
ImportError while importing test module 'D:\a\zxing-cpp\zxing-cpp\wrappers\python\test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
..\..\..\..\pypa\cibuildwheel\Cache\nuget-cpython\pythonx86.3.13.3\tools\Lib\importlib\__init__.py:88: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
D:\a\zxing-cpp\zxing-cpp\wrappers\python\test.py:6: in <module>
    import zxingcpp
E   ImportError: DLL load failed while importing zxingcpp: %1 is not a valid Win32 application.

(CI log)

@Doekin
Copy link

Doekin commented May 7, 2025

In my case, 32-bit Python 3.13 failed to import an extension built with the nanobind binding library, packaged as a cp312-abi3-win32 wheel.

After further investigation, I realized the issue was caused by a mistake in my build configuration. I had set the LIBRARY_OUTPUT_DIRECTORY property of the extension to ${CMAKE_CURRENT_SOURCE_DIR}, which caused the extension to be built in the same directory as CMakeLists.txt and test.py. This meant that during testing, the built extension in the project directory was prioritized over the one from the installed wheel.

This setup worked fine for Python versions 3.8 through 3.12, as the extension was rebuilt whenever the Python version or architecture changed. However, the issue arose when testing with 32-bit Python 3.13. Instead of using the installed 32-bit Python 3.12 stable ABI wheel, test.py mistakenly loaded the 64-bit extension previously built for 64-bit Python 3.12, which was still located in the project directory.

@joaospinto
Copy link
Author

I'm also using nanobind. Mostly followed https://github.com/wjakob/nanobind_example/tree/bazel and https://github.com/google/benchmark as examples of how to package Python libraries that use Bazel + Nanobind.

@nicholasjng
Copy link

Hey. I'm maintaining nanobind-bazel, which was used to build this particular wheel.

Py_LIMITED_API is set correctly during the build, but the linked libraries seem to be a bit off. I'm pretty sure this issue comes from Bazel linking the C++ extension with both python3.lib and python3X.lib, where X is the minor version of the used Python toolchain (3.12 in this case).

I'm currently wondering if this needs to be fixed upstream in rules_python - do you know by any chance if it's okay to link with both python3.lib and python3X.lib, or do you always need to pick the right one based on SABI yes/no? If not, I would first try to move python3.lib ahead of python3X.lib in the dependent libraries, since I think the dependency ordering is stable.

More information (including a linker command line from Bazel) in nicholasjng/nanobind-bazel#72.

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

4 participants