From 219d0361b7a98971f85f6d1cf70ff365429a3224 Mon Sep 17 00:00:00 2001 From: Arthur Lacote Date: Thu, 29 Oct 2026 17:54:01 +0100 Subject: [PATCH] FIX Use ctypes.util.dllist again on Windows and macOS #250 restricted the dllist import to Linux with Python 3.15+, so Windows and macOS on Python 3.14+ fell back to the older listing code. Restore the 3.7.0 behavior there and keep the Linux restriction. Co-Authored-By: Claude Opus 5.5 --- tests/test_threadpoolctl.py | 27 +++++++++++++++------------ threadpoolctl.py | 10 +++++++--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/tests/test_threadpoolctl.py b/tests/test_threadpoolctl.py index 080cc244..216ac757 100644 --- a/tests/test_threadpoolctl.py +++ b/tests/test_threadpoolctl.py @@ -37,17 +37,6 @@ ) -def stdlib_dllist(): - """Return ctypes.util.dllist when _load_libraries would use it, else None.""" - if sys.platform in ("linux", "emscripten"): - return None - try: - from ctypes.util import dllist - except ImportError: - return None - return dllist - - def is_old_openblas(lib_controller): # Possible bug in getting maximum number of threads with OpenBLAS < 0.2.16 # and OpenBLAS does not expose its version before 0.3.4. @@ -1014,6 +1003,20 @@ def test_threadpool_controller_repeated_init(): ThreadpoolController() +@pytest.mark.skipif( + sys.platform not in ("win32", "darwin") or sys.version_info[:2] < (3, 14), + reason="ctypes.util.dllist is only available on Python 3.14+", +) +def test_dllist_used_on_windows_and_macos(): + """Python 3.14+ lists libraries with ctypes.util.dllist on Windows and macOS.""" + calls = [] + controller = ThreadpoolController._from_controllers([]) + controller._find_libraries_with_python = calls.append + controller._load_libraries() + assert calls == [threadpoolctl.dllist] + assert threadpoolctl.dllist is not None + + def test_dllist_oserror_emits_warning(): """dllist listing failures warn instead of raising, so they can be reported.""" @@ -1087,7 +1090,7 @@ def test_windows_library_path_longer_than_max_path(tmp_path): @pytest.mark.skipif(sys.platform != "win32", reason="Windows-only test") @pytest.mark.skipif( - stdlib_dllist() is not None, + threadpoolctl.dllist is not None, reason="Python 3.14+ dllist does not apply the internal path length limit", ) def test_windows_library_path_exceeds_internal_limit(tmp_path, monkeypatch): diff --git a/threadpoolctl.py b/threadpoolctl.py index 47bc8e15..e22e8588 100644 --- a/threadpoolctl.py +++ b/threadpoolctl.py @@ -34,9 +34,13 @@ # builds (#225). dllist also uses dl_iterate_phdr internally (#239), which we # already avoid on Linux via /proc/self/maps on older versions of Python. dllist = None -if sys.platform != "emscripten" and ( - # Python 3.15 doesn't have the CFUNCTYPE anymore: - sys.platform == "linux" and sys.version_info[:2] >= (3, 15) +if ( + sys.platform != "emscripten" + and ( + sys.platform != "linux" + # Python 3.15 doesn't have the CFUNCTYPE anymore: + or sys.version_info[:2] >= (3, 15) + ) ): try: from ctypes.util import dllist