summaryrefslogtreecommitdiffstats
path: root/Lib/test/support
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-10-31 10:45:01 (GMT)
committerGitHub <noreply@github.com>2017-10-31 10:45:01 (GMT)
commit41efc402f154e48e95dde2993901648edcb24069 (patch)
treed3f35a640f0aca4cf244be2bbf8bf761a413587f /Lib/test/support
parent690c36f2f1085145d364a89bfed5944dd2470308 (diff)
downloadcpython-41efc402f154e48e95dde2993901648edcb24069.zip
cpython-41efc402f154e48e95dde2993901648edcb24069.tar.gz
cpython-41efc402f154e48e95dde2993901648edcb24069.tar.bz2
bpo-31629: Add support.SaveSignals (#4183) (#4187)
test_curses now saves/restores signals. On FreeBSD, the curses module sets handlers of some signals, but don't restore old handlers when the module is deinitialized. (cherry picked from commit 19f68301a1295a9c30d9f28b8f1479cdcccd75aa)
Diffstat (limited to 'Lib/test/support')
-rw-r--r--Lib/test/support/__init__.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index a5b8c46..c8feaa8 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -2621,3 +2621,42 @@ def disable_faulthandler():
finally:
if is_enabled:
faulthandler.enable(file=fd, all_threads=True)
+
+
+class SaveSignals:
+ """
+ Save an restore signal handlers.
+
+ This class is only able to save/restore signal handlers registered
+ by the Python signal module: see bpo-13285 for "external" signal
+ handlers.
+ """
+
+ def __init__(self):
+ import signal
+ self.signal = signal
+ self.signals = list(range(1, signal.NSIG))
+ # SIGKILL and SIGSTOP signals cannot be ignored nor catched
+ for signame in ('SIGKILL', 'SIGSTOP'):
+ try:
+ signum = getattr(signal, signame)
+ except AttributeError:
+ continue
+ self.signals.remove(signum)
+ self.handlers = {}
+
+ def save(self):
+ for signum in self.signals:
+ handler = self.signal.getsignal(signum)
+ if handler is None:
+ # getsignal() returns None if a signal handler was not
+ # registered by the Python signal module,
+ # and the handler is not SIG_DFL nor SIG_IGN.
+ #
+ # Ignore the signal: we cannot restore the handler.
+ continue
+ self.handlers[signum] = handler
+
+ def restore(self):
+ for signum, handler in self.handlers.items():
+ self.signal.signal(signum, handler)