1# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
2# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE
3# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt
4
5"""Astroid hooks for the signal library.
6
7The signal module generates the 'Signals', 'Handlers' and 'Sigmasks' IntEnums
8dynamically using the IntEnum._convert() classmethod, which modifies the module
9globals. Astroid is unable to handle this type of code.
10
11Without these hooks, the following are erroneously triggered by Pylint:
12 * E1101: Module 'signal' has no 'Signals' member (no-member)
13 * E1101: Module 'signal' has no 'Handlers' member (no-member)
14 * E1101: Module 'signal' has no 'Sigmasks' member (no-member)
15
16These enums are defined slightly differently depending on the user's operating
17system and platform. These platform differences should follow the current
18Python typeshed stdlib `signal.pyi` stub file, available at:
19
20* https://github.com/python/typeshed/blob/master/stdlib/signal.pyi
21
22Note that the enum.auto() values defined here for the Signals, Handlers and
23Sigmasks IntEnums are just dummy integer values, and do not correspond to the
24actual standard signal numbers - which may vary depending on the system.
25"""
26
27import sys
28
29from astroid.brain.helpers import register_module_extender
30from astroid.builder import parse
31from astroid.manager import AstroidManager
32
33
34def _signals_enums_transform():
35 """Generates the AST for 'Signals', 'Handlers' and 'Sigmasks' IntEnums."""
36 return parse(_signals_enum() + _handlers_enum() + _sigmasks_enum())
37
38
39def _signals_enum() -> str:
40 """Generates the source code for the Signals int enum."""
41 signals_enum = """
42 import enum
43 class Signals(enum.IntEnum):
44 SIGABRT = enum.auto()
45 SIGEMT = enum.auto()
46 SIGFPE = enum.auto()
47 SIGILL = enum.auto()
48 SIGINFO = enum.auto()
49 SIGINT = enum.auto()
50 SIGSEGV = enum.auto()
51 SIGTERM = enum.auto()
52 """
53 if sys.platform != "win32":
54 signals_enum += """
55 SIGALRM = enum.auto()
56 SIGBUS = enum.auto()
57 SIGCHLD = enum.auto()
58 SIGCONT = enum.auto()
59 SIGHUP = enum.auto()
60 SIGIO = enum.auto()
61 SIGIOT = enum.auto()
62 SIGKILL = enum.auto()
63 SIGPIPE = enum.auto()
64 SIGPROF = enum.auto()
65 SIGQUIT = enum.auto()
66 SIGSTOP = enum.auto()
67 SIGSYS = enum.auto()
68 SIGTRAP = enum.auto()
69 SIGTSTP = enum.auto()
70 SIGTTIN = enum.auto()
71 SIGTTOU = enum.auto()
72 SIGURG = enum.auto()
73 SIGUSR1 = enum.auto()
74 SIGUSR2 = enum.auto()
75 SIGVTALRM = enum.auto()
76 SIGWINCH = enum.auto()
77 SIGXCPU = enum.auto()
78 SIGXFSZ = enum.auto()
79 """
80 if sys.platform == "win32":
81 signals_enum += """
82 SIGBREAK = enum.auto()
83 """
84 if sys.platform not in ("darwin", "win32"):
85 signals_enum += """
86 SIGCLD = enum.auto()
87 SIGPOLL = enum.auto()
88 SIGPWR = enum.auto()
89 SIGRTMAX = enum.auto()
90 SIGRTMIN = enum.auto()
91 """
92 return signals_enum
93
94
95def _handlers_enum() -> str:
96 """Generates the source code for the Handlers int enum."""
97 return """
98 import enum
99 class Handlers(enum.IntEnum):
100 SIG_DFL = enum.auto()
101 SIG_IGN = eunm.auto()
102 """
103
104
105def _sigmasks_enum() -> str:
106 """Generates the source code for the Sigmasks int enum."""
107 if sys.platform != "win32":
108 return """
109 import enum
110 class Sigmasks(enum.IntEnum):
111 SIG_BLOCK = enum.auto()
112 SIG_UNBLOCK = enum.auto()
113 SIG_SETMASK = enum.auto()
114 """
115 return ""
116
117
118def register(manager: AstroidManager) -> None:
119 register_module_extender(manager, "signal", _signals_enums_transform)