From c2619df360881ac9de74567beeb25e18753de62a Mon Sep 17 00:00:00 2001 From: Patrick St-Louis Date: Fri, 20 Feb 2026 11:23:27 -0500 Subject: [PATCH 1/2] fix(utils): satisfy Sonar S7497 in timeout shim (cleanup + intentional TimeoutError) Signed-off-by: Patrick St-Louis --- acapy_agent/utils/repeat.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acapy_agent/utils/repeat.py b/acapy_agent/utils/repeat.py index 910960e5f2..b5251980f2 100644 --- a/acapy_agent/utils/repeat.py +++ b/acapy_agent/utils/repeat.py @@ -105,7 +105,9 @@ async def _timeout_gen(): try: yield except asyncio.CancelledError as exc: - raise asyncio.TimeoutError from exc + handle.cancel() # cleanup before raising + # Intentional: convert to TimeoutError for asyncio.timeout() API compatibility + raise asyncio.TimeoutError from exc # NOSONAR python:S7497 finally: handle.cancel() From 86c759ff8e85473749874a6bd7da6df9077082bc Mon Sep 17 00:00:00 2001 From: Patrick St-Louis Date: Fri, 20 Feb 2026 11:26:14 -0500 Subject: [PATCH 2/2] fix(utils): remove Python <3.11 timeout shim; use asyncio.timeout only (fixes Sonar S7497) Signed-off-by: Patrick St-Louis --- acapy_agent/utils/repeat.py | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/acapy_agent/utils/repeat.py b/acapy_agent/utils/repeat.py index b5251980f2..3cab4c5327 100644 --- a/acapy_agent/utils/repeat.py +++ b/acapy_agent/utils/repeat.py @@ -1,7 +1,6 @@ """Utils for repeating tasks.""" import asyncio -from contextlib import asynccontextmanager from typing import Optional @@ -93,22 +92,5 @@ def __repr__(self) -> str: def _timeout_cm(duration: float): - """Compatibility wrapper for asyncio.timeout (Python <3.11).""" - if hasattr(asyncio, "timeout"): - return asyncio.timeout(duration) - - @asynccontextmanager - async def _timeout_gen(): - loop = asyncio.get_running_loop() - task = asyncio.current_task() - handle = loop.call_later(duration, task.cancel) - try: - yield - except asyncio.CancelledError as exc: - handle.cancel() # cleanup before raising - # Intentional: convert to TimeoutError for asyncio.timeout() API compatibility - raise asyncio.TimeoutError from exc # NOSONAR python:S7497 - finally: - handle.cancel() - - return _timeout_gen() + """Async context manager that times out after duration (asyncio.timeout).""" + return asyncio.timeout(duration)