1 import _signal
2 from _signal import *
3 from enum import IntEnum as _IntEnum
4
5 _globals = globals()
6
7 _IntEnum._convert_(
8 'Signals', __name__,
9 lambda name:
10 name.isupper()
11 and (name.startswith('SIG') and not name.startswith('SIG_'))
12 or name.startswith('CTRL_'))
13
14 _IntEnum._convert_(
15 'Handlers', __name__,
16 lambda name: name in ('SIG_DFL', 'SIG_IGN'))
17
18 if 'pthread_sigmask' in _globals:
19 _IntEnum._convert_(
20 'Sigmasks', __name__,
21 lambda name: name in ('SIG_BLOCK', 'SIG_UNBLOCK', 'SIG_SETMASK'))
22
23
24 def _int_to_enum(value, enum_klass):
25 """Convert a numeric value to an IntEnum member.
26 If it's not a known member, return the numeric value itself.
27 """
28 try:
29 return enum_klass(value)
30 except ValueError:
31 return value
32
33
34 def _enum_to_int(value):
35 """Convert an IntEnum member to a numeric value.
36 If it's not an IntEnum member return the value itself.
37 """
38 try:
39 return int(value)
40 except (ValueError, TypeError):
41 return value
42
43
44 # Similar to functools.wraps(), but only assign __doc__.
45 # __module__ should be preserved,
46 # __name__ and __qualname__ are already fine,
47 # __annotations__ is not set.
48 def _wraps(wrapped):
49 def decorator(wrapper):
50 wrapper.__doc__ = wrapped.__doc__
51 return wrapper
52 return decorator
53
54 @_wraps(_signal.signal)
55 def signal(signalnum, handler):
56 handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
57 return _int_to_enum(handler, Handlers)
58
59
60 @_wraps(_signal.getsignal)
61 def getsignal(signalnum):
62 handler = _signal.getsignal(signalnum)
63 return _int_to_enum(handler, Handlers)
64
65
66 if 'pthread_sigmask' in _globals:
67 @_wraps(_signal.pthread_sigmask)
68 def pthread_sigmask(how, mask):
69 sigs_set = _signal.pthread_sigmask(how, mask)
70 return set(_int_to_enum(x, Signals) for x in sigs_set)
71
72
73 if 'sigpending' in _globals:
74 @_wraps(_signal.sigpending)
75 def sigpending():
76 return {_int_to_enum(x, Signals) for x in _signal.sigpending()}
77
78
79 if 'sigwait' in _globals:
80 @_wraps(_signal.sigwait)
81 def sigwait(sigset):
82 retsig = _signal.sigwait(sigset)
83 return _int_to_enum(retsig, Signals)
84
85
86 if 'valid_signals' in _globals:
87 @_wraps(_signal.valid_signals)
88 def valid_signals():
89 return {_int_to_enum(x, Signals) for x in _signal.valid_signals()}
90
91
92 del _globals, _wraps