ITADN

Termux interrupted-update recovery loop: wrong extras group + no reset path (related to #39106), plus unrelated Python 3.14 ThreadPoolExecutor incompatibility in daemon_pool.py

#88896Opencodetheo75 创建于 1 天前
type/bugcomp/cliP2needs-reprosweeper:risk-compatibilityarea/install-update
C
codetheo75commented
## Section 1: Termux update/recovery extras-group bug Cross-reference existing issue #39106, which documents `cmd_update` on Termux defaulting to `.[all]` instead of `.[termux-all]`, causing `cryptography` wheel-build failures (`cryptography-50.0.0-cp314-abi3-android_28_arm64_v8a.whl is not compatible with the current Python 3.14 on Android`). Report that the same bug also exists in the interrupted-update recovery path in `hermes_cli/_early_recovery.py` (near the "Pending interrupted-update install has already failed 3 times" message), which fires on *every* command (`hermes status`, `hermes doctor`, etc.) whenever `.update-incomplete` exists — broader impact than #39106 describes. We did not capture exact line numbers; ask maintainers to check that file's dependency-install call for the same missing `_is_termux_env()` detection that `cmd_setup` already has. Also report: there's no supported way to clear a stuck `.update-incomplete` marker once resolved manually — it's only cleared by `cmd_update`'s own internal success path. Suggest a `hermes update --reset-state` command that clears it after confirming the environment imports cleanly. ## Section 2: Python 3.14 ThreadPoolExecutor incompatibility in daemon_pool.py `tools/daemon_pool.py`'s `DaemonThreadPoolExecutor._adjust_thread_count()` calls the internal `concurrent.futures.thread._worker()` function using the old signature and argument order: ```python args=( weakref.ref(self, weakref_cb), self._work_queue, self._initializer, self._initargs, ) ``` Python 3.14 changed `_worker()`'s signature to `(executor_reference, ctx, work_queue)`, replacing `initializer`/`initargs` with a `WorkerContext` object produced by `self._create_worker_context()` (set up in `ThreadPoolExecutor.__init__` via `type(self).prepare_context(initializer, initargs, **ctxkwargs)`). The old code fails immediately under Python 3.14 with: ```text TypeError: _worker() takes 3 positional arguments but 4 were given ``` An intermediate fix attempt using `self._thread_context` also fails, since that attribute doesn't exist in 3.14: ```text AttributeError: 'DaemonThreadPoolExecutor' object has no attribute '_thread_context' ``` The correct fix, verified working (test passed: `HERMES_EXECUTOR_OK`): ```python def _adjust_thread_count(self) -> None: if self._idle_semaphore.acquire(timeout=0): return def weakref_cb(_, q=self._work_queue): q.put(None) num_threads = len(self._threads) if num_threads < self._max_workers: thread_name = "%s_%d" % (self._thread_name_prefix or self, num_threads) t = threading.Thread( name=thread_name, target=_worker, args=( weakref.ref(self, weakref_cb), self._create_worker_context(), self._work_queue, ), daemon=True, ) t.start() self._threads.add(t) ``` Note this deliberately preserves Hermes' original behavior of not registering the thread in `_threads_queues`, keeping it a true daemon thread. Ask whether this is already tracked elsewhere before filing as new, since it may affect any Hermes install on Python 3.14+ regardless of platform, not just Termux. ## Environment for both - Hermes Agent 0.20.3 - Termux on Android - aarch64 / Samsung device - Python 3.14.6 ## Verification notes - The `.[termux-all]` fix, marker removal, and `daemon_pool.py` patch were all verified working locally. - `hermes update` itself was not re-tested after the fix — describe it as "avoided," not "confirmed fixed."
0 条评论