Skip to content

Commit 38a783d

Browse files
committed
signal checks
1 parent 6104f14 commit 38a783d

File tree

5 files changed

+47
-5
lines changed

5 files changed

+47
-5
lines changed

docs/changelog.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ icon: paste
44
# Changelog
55

66
---
7-
## v0.2.0 [!badge text="LATEST" variant="info"]
7+
## v0.2.1 [!badge text="LATEST" variant="info"]
8+
9+
Released: [2025-02-22](https://github.com/haizelabs/verdict/releases/tag/v0.2.1)
10+
- Signal handler check for NVidia NeMo-Guardrails integration
11+
12+
## v0.2.0
813

914
Released: [2025-02-19](https://github.com/haizelabs/verdict/releases/tag/v0.2.0)
1015
- Initial public release.

docs/retype.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ url: verdict.haizelabs.com/docs
44

55
branding:
66
title: Verdict
7-
label: 0.2.0
7+
label: 0.2.1
88
logo: /static/logos/logo.png
99
logoDark: /static/logos/logo.png
1010
logoAlign: left

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ issues = "https://github.com/haizelabs/verdict/issues"
1313

1414
[project]
1515
name = "verdict"
16-
version = "0.2.0"
16+
version = "0.2.1"
1717
authors = [{ name = "Nimit Kalra", email = "[email protected]" }]
1818
license = { text = "MIT License" }
1919
description = "LLM evaluation pipelines"

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

verdict/util/misc.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,43 @@
11
from __future__ import annotations
22

33
import logging
4+
import os
45
import signal
6+
import sys
7+
import threading
58
from functools import wraps
69
from typing import Any, Callable, Optional, Type
710

811

12+
def is_signal_safe():
13+
"""
14+
Strictly check if the current environment is safe for signal handling.
15+
16+
Returns:
17+
bool: True only if ALL signal safety conditions are met
18+
"""
19+
# Must be in the main thread
20+
if threading.current_thread() is not threading.main_thread():
21+
return False
22+
23+
# Must be in the main interpreter
24+
if not hasattr(sys, 'argv'):
25+
return False
26+
27+
# Check if we're in a forked process
28+
if os.getpid() != os.getppid():
29+
return False
30+
31+
# Additional interpreter state checks
32+
if not sys.modules.get('__main__'):
33+
return False
34+
35+
# Check if the interpreter is shutting down
36+
if sys is None or threading is None:
37+
return False
38+
39+
return True
40+
941
def keyboard_interrupt_safe(func: Callable[[Any], Any]) -> Callable[[Any], Any]:
1042
@wraps(func)
1143
def wrapped(self: Any, *args, **kwargs) -> Any:
@@ -18,7 +50,11 @@ def wrapped(self: Any, *args, **kwargs) -> Any:
1850
self.executor.graceful_shutdown()
1951
finally:
2052
signal.signal(signal.SIGINT, original_handler)
21-
return wrapped
53+
54+
if is_signal_safe():
55+
return wrapped
56+
else:
57+
return func
2258

2359
class DisableLogger:
2460
def __init__(self, logger_name: str, all: bool=False) -> None:
@@ -40,3 +76,4 @@ def __exit__(self, exc_type, exc_value, traceback) -> None:
4076
def lightweight(cls: Type) -> Type:
4177
cls.lightweight = True
4278
return cls
79+

0 commit comments

Comments
 (0)