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
27
28import sys
29
30from astroid.brain.helpers import register_module_extender
31from astroid.builder import parse
32from astroid.manager import AstroidManager
33
34
35def _signals_enums_transform():
36 """Generates the AST for 'Signals', 'Handlers' and 'Sigmasks' IntEnums."""
37 return parse(_signals_enum() + _handlers_enum() + _sigmasks_enum())
38
39
40def _signals_enum() -> str:
41 """Generates the source code for the Signals int enum."""
42 signals_enum = """
43 import enum
44 class Signals(enum.IntEnum):
45 SIGABRT = enum.auto()
46 SIGEMT = enum.auto()
47 SIGFPE = enum.auto()
48 SIGILL = enum.auto()
49 SIGINFO = enum.auto()
50 SIGINT = enum.auto()
51 SIGSEGV = enum.auto()
52 SIGTERM = enum.auto()
53 """
54 if sys.platform != "win32":
55 signals_enum += """
56 SIGALRM = enum.auto()
57 SIGBUS = enum.auto()
58 SIGCHLD = enum.auto()
59 SIGCONT = enum.auto()
60 SIGHUP = enum.auto()
61 SIGIO = enum.auto()
62 SIGIOT = enum.auto()
63 SIGKILL = enum.auto()
64 SIGPIPE = enum.auto()
65 SIGPROF = enum.auto()
66 SIGQUIT = enum.auto()
67 SIGSTOP = enum.auto()
68 SIGSYS = enum.auto()
69 SIGTRAP = enum.auto()
70 SIGTSTP = enum.auto()
71 SIGTTIN = enum.auto()
72 SIGTTOU = enum.auto()
73 SIGURG = enum.auto()
74 SIGUSR1 = enum.auto()
75 SIGUSR2 = enum.auto()
76 SIGVTALRM = enum.auto()
77 SIGWINCH = enum.auto()
78 SIGXCPU = enum.auto()
79 SIGXFSZ = enum.auto()
80 """
81 if sys.platform == "win32":
82 signals_enum += """
83 SIGBREAK = enum.auto()
84 """
85 if sys.platform not in ("darwin", "win32"):
86 signals_enum += """
87 SIGCLD = enum.auto()
88 SIGPOLL = enum.auto()
89 SIGPWR = enum.auto()
90 SIGRTMAX = enum.auto()
91 SIGRTMIN = enum.auto()
92 """
93 return signals_enum
94
95
96def _handlers_enum() -> str:
97 """Generates the source code for the Handlers int enum."""
98 return """
99 import enum
100 class Handlers(enum.IntEnum):
101 SIG_DFL = enum.auto()
102 SIG_IGN = eunm.auto()
103 """
104
105
106def _sigmasks_enum() -> str:
107 """Generates the source code for the Sigmasks int enum."""
108 if sys.platform != "win32":
109 return """
110 import enum
111 class Sigmasks(enum.IntEnum):
112 SIG_BLOCK = enum.auto()
113 SIG_UNBLOCK = enum.auto()
114 SIG_SETMASK = enum.auto()
115 """
116 return ""
117
118
119def register(manager: AstroidManager) -> None:
120 register_module_extender(manager, "signal", _signals_enums_transform)