From 7a7a371c593b8956f8d6f0bb588d2d6afdc8d428 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 26 Aug 2026 15:43:37 -0700 Subject: [PATCH] fix: harden claim-release guard for bare test doubles; repoint source-pinning test at the impl The wrapper now getattr-defaults _processed_message_ts (object.__new__ adapters in sibling suites lack it), and the reaction-guard source pin reads _handle_slack_message_impl where the production expression lives. --- plugins/platforms/slack/adapter.py | 14 +++++++++++--- tests/gateway/test_slack_mention.py | 4 +++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/platforms/slack/adapter.py b/plugins/platforms/slack/adapter.py index cd848c4bc5..7debfb6616 100644 --- a/plugins/platforms/slack/adapter.py +++ b/plugins/platforms/slack/adapter.py @@ -5959,12 +5959,20 @@ class SlackAdapter(BasePlatformAdapter): started (the sequential-suppression case) is left untouched. """ _ts = str((event or {}).get("ts") or "") - _was_claimed = bool(_ts) and _ts in self._processed_message_ts + # getattr: bare test doubles (object.__new__) may lack the map. + _claims = getattr(self, "_processed_message_ts", None) + _was_claimed = bool(_ts) and _claims is not None and _ts in _claims try: return await self._handle_slack_message_impl(event, payload) except BaseException: - if _ts and not _was_claimed and _ts in self._processed_message_ts: - self._processed_message_ts.pop(_ts, None) + _claims = getattr(self, "_processed_message_ts", None) + if ( + _ts + and not _was_claimed + and _claims is not None + and _ts in _claims + ): + _claims.pop(_ts, None) logger.warning( "[%s] handler failed after claiming ts=%s; claim released " "so a retry or edit can re-drive the turn", diff --git a/tests/gateway/test_slack_mention.py b/tests/gateway/test_slack_mention.py index a3d3aed0b8..2a52eea832 100644 --- a/tests/gateway/test_slack_mention.py +++ b/tests/gateway/test_slack_mention.py @@ -263,7 +263,9 @@ def test_reaction_guard_pinned_to_production_expression(): (back to ``is_dm or is_mentioned``, which reacts to unmentioned MPIMs) fails here instead of silently passing a self-referential lambda. """ - src = inspect.getsource(SlackAdapter._handle_slack_message) + # The public method is a thin claim-release guard; the production + # expression lives in the impl. + src = inspect.getsource(SlackAdapter._handle_slack_message_impl) assert "(is_one_to_one_dm or is_mentioned)" in src, ( "reaction guard no longer keys off is_one_to_one_dm — an unmentioned " "MPIM would react again (regression of the group-DM fix)"