fix(daemon-pool): support Python 3.14 _worker signature change (#58596) - #58699
fix(daemon-pool): support Python 3.14 _worker signature change (#58596)#58699nankingjing wants to merge 3 commits into
Conversation
…esearch#58596) Python 3.14 changed _worker from 4 params to 3 params, replacing initializer/initargs with a WorkerContext. Detect the signature at import time and branch in _adjust_thread_count so DaemonThreadPoolExecutor works on both Python <= 3.13 and >= 3.14.
Duplicate of #57459 (earlier open PR, created 2026-07-03). Both patch the same site -- |
AmirF194
left a comment
There was a problem hiding this comment.
The arg-order handling is correct. I checked the CPython 3.14 source and _worker(executor_reference, ctx, work_queue) matches what you pass, and _create_worker_context is a genuine instance attribute set in ThreadPoolExecutor.__init__, so the call resolves. The <=3.13 branch is identical to the original tuple, so this is a clean no-op on the versions we currently ship. I ran tests/tools/test_daemon_pool.py in a clean Python 3.11 container matching CI: 8 passed.
Two things worth sorting before this lands, neither a bug in the diff itself.
First, pyproject.toml still pins requires-python = ">=3.11,<3.14", so a standard install will not even run on 3.14 and the fix is only reachable if you bypass that constraint. Do you want to bump the ceiling in this same PR so the fix is actually usable, or is the intent to hold off on 3.14 for now? That decision changes whether this should merge yet.
Second, the 3.14 path has no test coverage. CI provisions only 3.11, and each test here exercises whichever branch the running interpreter picks. I confirmed this directly: reverting daemon_pool.py to main makes the module fail to import (_WORKER_USES_CTX no longer exists) rather than fail a behavioral assertion, so on 3.11 the new tuple could be wrong and nothing would catch it. Could you add a test that patches _WORKER_USES_CTX = True and asserts the exact args tuple passed to the thread target, so the 3.14 branch is validated even when we run on 3.11? A 3.14 CI slice would be ideal, but the mocked test is the cheap floor.
Add two tests that mock _WORKER_USES_CTX to validate the 3.14 code path even when the suite runs on Python 3.11 (CI provisioned version): - test_py314_branch_args_tuple_shape: mocks _WORKER_USES_CTX=True and _create_worker_context to assert the 3-element args tuple shape (executor_ref, worker_context, work_queue) is passed to Thread(). - test_py313_branch_args_tuple_shape: asserts the legacy 4-element tuple on <= 3.13 interpreters. Before this, reverting daemon_pool.py to main made the module fail to import on 3.11 because _WORKER_USES_CTX no longer existed — a wrong tuple on the 3.14 path would not be caught by any test. These mocks close that coverage gap.
|
Thanks for the thorough review, @AmirF194. Two responses: 1. Mocked test for 3.14 branch (done) I've added 2. pyproject.toml ceiling: keep The |
|
Fair flag — this does overlap #57459 (@gysyl), same call site in `_adjust_thread_count`. One substantive difference for whoever consolidates: the two fixes are not equivalent on real 3.14.
@AmirF194 verified the arg order against the CPython 3.14 source and ran the suite green. Happy to defer to maintainers on which to land or whether to consolidate — just noting the mechanism difference is load-bearing here, not cosmetic. |
|
Verified: branch is cleanly rebaseable on main (merge-base 1388cd1, test merge succeeds). The _worker signature detection at import time is a clean approach, and the mocked 3.14 test gives CI coverage on all Python versions. No conflicts, no surprises. |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for adding a targeted cross-version fix and a mocked 3.14-path test. The implementation addresses the current main compatibility gap in tools/daemon_pool.py:55-59; its context argument order also matches CPython 3.14’s _worker(executor_reference, ctx, work_queue) contract (Lib/concurrent/futures/thread.py:97).
Problems
tests/tools/test_daemon_pool.py:197assertsnot _WORKER_USES_CTX. On CPython 3.14, the PR computes that flag as true from the three-parameter_workersignature (tools/daemon_pool.py:39), so this test fails on the target interpreter rather than being skipped.
Suggested changes
- Mark the legacy-shape test skipped when
_WORKER_USES_CTXis true, or otherwise make its assertion conditional on the legacy runtime.
Automated hermes-sweeper review.
| pool = DaemonThreadPoolExecutor( | ||
| max_workers=1, initializer=lambda: None, initargs=() | ||
| ) | ||
| assert not _WORKER_USES_CTX, ( |
There was a problem hiding this comment.
On CPython 3.14 this flag is true by construction because _worker has the new three-argument signature, so this test fails on the target interpreter. Please skip this legacy-path test when _WORKER_USES_CTX is true, rather than asserting the runner is <=3.13.
There was a problem hiding this comment.
Fixed in b88d4fb — replaced the hard assert not _WORKER_USES_CTX with @pytest.mark.skipif(_WORKER_USES_CTX, reason="legacy 4-arg _worker signature only exists on Python <= 3.13"), so the legacy-shape test skips on 3.14+ instead of asserting the interpreter version. Verified both ways: Python 3.12 → 10 passed (test still exercised); CPython 3.14 → 9 passed, 1 skipped with that reason.
test_py313_branch_args_tuple_shape hard-asserted 'not _WORKER_USES_CTX', which fails on CPython 3.14 where the flag is legitimately computed True from the three-parameter _worker signature. Replace the interpreter assertion with @pytest.mark.skipif so the legacy-shape test skips on 3.14+ instead of failing. Verified: 10 passed on 3.12 (test still runs); 9 passed / 1 skipped on 3.14.
b88d4fb to
3494b2b
Compare
Summary
Python 3.14 changed
_workerfrom 4 params to 3 params, replacinginitializer/initargswith aWorkerContext. This causedDaemonThreadPoolExecutor._adjust_thread_countto crash withAttributeError: DaemonThreadPoolExecutor object has no attribute _initializer.Fix
_workersignature at import time viainspect.signature_adjust_thread_count:self._create_worker_context()as the ctx argself._initializer/self._initargsas beforeFiles changed
tools/daemon_pool.py— add signature detection and version branchtests/tools/test_daemon_pool.py— 4 regression testsTest results
All 4 existing tests + 4 new regression tests pass on Python 3.11 (which exercises the <= 3.13 code path).
Closes #58596