From f194ab05b77164f42a7ddeca4cf6b44b93e3e191 Mon Sep 17 00:00:00 2001 From: Arbaaz Ahmed Date: Sun, 25 Jan 2026 15:12:30 +0530 Subject: [PATCH 1/2] Replace runtime assert with explicit TypeError in interrupt handling Signed-off-by: Arbaaz Ahmed --- src/scancode/interrupt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/scancode/interrupt.py b/src/scancode/interrupt.py index e26d090567d..1be5328ae54 100644 --- a/src/scancode/interrupt.py +++ b/src/scancode/interrupt.py @@ -167,7 +167,10 @@ def async_raise(tid, exctype=Exception): from http://tomerfiliba.com/recipes/Thread2/ license: public domain. """ - assert isinstance(tid, int), 'Invalid thread id: must an integer' + if not isinstance(tid, int): + raise TypeError( + f"Invalid thread id: must be an integer, got {type(tid).__name__}" + ) tid = c_long(tid) exception = py_object(Exception) From 569c72caad4aab8c84d16a44241b5a44c1fad438 Mon Sep 17 00:00:00 2001 From: Arbaaz Ahmed Date: Sun, 25 Jan 2026 18:40:58 +0530 Subject: [PATCH 2/2] Gracefully handle signal setup failure in interruptible Signed-off-by: Arbaaz Ahmed --- src/scancode/interrupt.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/scancode/interrupt.py b/src/scancode/interrupt.py index 1be5328ae54..1a21306cce7 100644 --- a/src/scancode/interrupt.py +++ b/src/scancode/interrupt.py @@ -86,9 +86,20 @@ def handler(signum, frame): raise TimeoutError try: - create_signal(SIGALRM, handler) - setitimer(ITIMER_REAL, timeout) - return NO_ERROR, func(*(args or ()), **(kwargs or {})) + create_signal(SIGALRM, handler) + setitimer(ITIMER_REAL, timeout) +except (ValueError, TypeError): + # Signals only work in the main thread. + # If we cannot install them, continue without interrupt support. + return NO_ERROR, func(*(args or ()), **(kwargs or {})) + + try: + return NO_ERROR, func(*(args or ()), **(kwargs or {})) + except TimeoutError: + return TIMEOUT_MSG % locals(), NO_VALUE + except Exception: + return ERROR_MSG + traceback_format_exc(), NO_VALUE + except TimeoutError: return TIMEOUT_MSG % locals(), NO_VALUE