-
Notifications
You must be signed in to change notification settings - Fork 72
/
ctx_managers.py
77 lines (62 loc) · 1.59 KB
/
ctx_managers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python
"""
Various signal-related context managers
"""
from contextlib import contextmanager
import signal
@contextmanager
def ExceptionOnSignal(s=signal.SIGUSR1, e=Exception, i=None):
"""
Raise a specific exception when the specified signal is detected.
"""
def handler(signum, frame):
if i is not None:
raise e('signal %i detected in %s' % (s, i))
else:
raise e('signal %i detected' % s)
signal.signal(s, handler)
yield
@contextmanager
def TryExceptionOnSignal(s=signal.SIGUSR1, e=Exception, i=None):
"""
Check for exception raised in response to specific signal.
"""
with ExceptionOnSignal(s, e, i):
try:
yield
except e:
pass
@contextmanager
def IgnoreSignal(s=signal.SIGUSR1):
"""
Ignore the specified signal.
"""
signal.signal(s, signal.SIG_IGN)
yield
@contextmanager
def IgnoreKeyboardInterrupt():
"""
Ignore keyboard interrupts.
"""
signal.signal(signal.SIGINT, signal.SIG_IGN)
yield
@contextmanager
def OnKeyboardInterrupt(handler):
"""
Respond to keyboard interrupt with specified handler.
"""
signal.signal(signal.SIGINT, handler)
yield
if __name__ == '__main__':
# This example should quit when Ctrl-C is pressed:
import time
def handler(signum, frame):
print('caught')
handler.done = True
handler.done = False
with OnKeyboardInterrupt(handler):
while True:
print('waiting')
time.sleep(1)
if handler.done:
break