• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import _signal
2from _signal import *
3from 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
18if 'pthread_sigmask' in _globals:
19    _IntEnum._convert_(
20            'Sigmasks', __name__,
21            lambda name: name in ('SIG_BLOCK', 'SIG_UNBLOCK', 'SIG_SETMASK'))
22
23
24def _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
34def _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.
48def _wraps(wrapped):
49    def decorator(wrapper):
50        wrapper.__doc__ = wrapped.__doc__
51        return wrapper
52    return decorator
53
54@_wraps(_signal.signal)
55def 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)
61def getsignal(signalnum):
62    handler = _signal.getsignal(signalnum)
63    return _int_to_enum(handler, Handlers)
64
65
66if '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
73if 'sigpending' in _globals:
74    @_wraps(_signal.sigpending)
75    def sigpending():
76        return {_int_to_enum(x, Signals) for x in _signal.sigpending()}
77
78
79if '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
86if '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
92del _globals, _wraps
93