From 3e35fcd90f52a2359c634232a2a45d4966326fbb Mon Sep 17 00:00:00 2001 From: Martin Nygren Date: Tue, 22 Sep 2026 07:38:22 +0100 Subject: [PATCH 1/2] Make set_max_threads() discard its argument, matching documentation The binding warned that user_threads was ignored but still forwarded it to SetMaxThreads(), coupling the binding to legacy behavior. Discard the parameter and always call SetMaxThreads(0). Co-Authored-By: Claude Sonnet 5 --- python/src/bindings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/bindings.cpp b/python/src/bindings.cpp index b111e219..c11b4e15 100644 --- a/python/src/bindings.cpp +++ b/python/src/bindings.cpp @@ -644,7 +644,7 @@ auto register_analysis_bindings(py::module_& module) -> void // count argument is ignored; retained only for backward compatibility. module.def( "set_max_threads", - [](const int user_threads) { + [](const int /*user_threads*/) { if (PyErr_WarnEx( PyExc_DeprecationWarning, "set_max_threads() is deprecated; use initialize_static_memory(). " @@ -653,7 +653,7 @@ auto register_analysis_bindings(py::module_& module) -> void throw py::error_already_set(); } py::gil_scoped_release release; - SetMaxThreads(user_threads); + SetMaxThreads(0); }, py::arg("user_threads") = 0, "DEPRECATED: use initialize_static_memory() instead.\n\n" From 9b565fd870d8eabc336d8454dcb29ac0cf09cbc7 Mon Sep 17 00:00:00 2001 From: Martin Nygren Date: Tue, 22 Sep 2026 14:36:15 +0100 Subject: [PATCH 2/2] Fix stale negative-value claim in set_max_threads() docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copilot flagged that the docs promised ValueError for negative user_threads, but the binding has never validated the sign — it is always ignored, including negative values. Correct the docs to match actual behavior and add regression tests locking in that a negative value is accepted, not rejected. Co-Authored-By: Claude Sonnet 5 --- docs/python_interface.md | 3 ++- python/tests/test_analyse.py | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/python_interface.md b/docs/python_interface.md index 6c856291..ad34b352 100644 --- a/docs/python_interface.md +++ b/docs/python_interface.md @@ -280,7 +280,8 @@ This does **not** control DDS's batch parallelism and is kept only for backward compatibility. `solve_all_boards_*` already parallelize across the machine's hardware threads automatically (via `solve_boards_n`) — the value passed here does not size that pool. `analyse_all_plays_pbn` currently runs sequentially. -`user_threads` must be `>= 0` (`0` = auto); raises `ValueError` for negative values. +`user_threads` is ignored regardless of value (including negative values) — it +is accepted only for backward compatibility with the legacy call signature. For per-board concurrency from Python, create one `SolverContext` per worker thread and pass it to `solve_board` / `solve_board_pbn` (which release the GIL during the diff --git a/python/tests/test_analyse.py b/python/tests/test_analyse.py index 544c5b3e..376b3bc9 100644 --- a/python/tests/test_analyse.py +++ b/python/tests/test_analyse.py @@ -1,4 +1,4 @@ -"""Tests for analyse_play_pbn, analyse_all_plays_pbn and dealer_par.""" +"""Tests for analyse_play_pbn, analyse_all_plays_pbn, dealer_par and set_max_threads.""" import unittest @@ -92,5 +92,22 @@ def test_dealer_par_invalid_vulnerability(self) -> None: dealer_par(dd_table, dealer=0, vulnerable=9) +class TestSetMaxThreads(unittest.TestCase): + """Tests for the deprecated set_max_threads() thread-resource hook. + + user_threads is ignored regardless of value (see docs/python_interface.md); + it is accepted only for backward compatibility with the legacy call + signature, so a negative value must not be rejected. + """ + + def test_negative_user_threads_is_ignored_not_rejected(self) -> None: + with self.assertWarns(DeprecationWarning): + set_max_threads(-1) + + def test_emits_deprecation_warning(self) -> None: + with self.assertWarns(DeprecationWarning): + set_max_threads(0) + + if __name__ == "__main__": unittest.main()