Skip to content

Commit 41efc40

Browse files
authored
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 19f6830)
1 parent 690c36f commit 41efc40

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

Lib/test/support/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2621,3 +2621,42 @@ def disable_faulthandler():
26212621
finally:
26222622
if is_enabled:
26232623
faulthandler.enable(file=fd, all_threads=True)
2624+
2625+
2626+
class SaveSignals:
2627+
"""
2628+
Save an restore signal handlers.
2629+
2630+
This class is only able to save/restore signal handlers registered
2631+
by the Python signal module: see bpo-13285 for "external" signal
2632+
handlers.
2633+
"""
2634+
2635+
def __init__(self):
2636+
import signal
2637+
self.signal = signal
2638+
self.signals = list(range(1, signal.NSIG))
2639+
# SIGKILL and SIGSTOP signals cannot be ignored nor catched
2640+
for signame in ('SIGKILL', 'SIGSTOP'):
2641+
try:
2642+
signum = getattr(signal, signame)
2643+
except AttributeError:
2644+
continue
2645+
self.signals.remove(signum)
2646+
self.handlers = {}
2647+
2648+
def save(self):
2649+
for signum in self.signals:
2650+
handler = self.signal.getsignal(signum)
2651+
if handler is None:
2652+
# getsignal() returns None if a signal handler was not
2653+
# registered by the Python signal module,
2654+
# and the handler is not SIG_DFL nor SIG_IGN.
2655+
#
2656+
# Ignore the signal: we cannot restore the handler.
2657+
continue
2658+
self.handlers[signum] = handler
2659+
2660+
def restore(self):
2661+
for signum, handler in self.handlers.items():
2662+
self.signal.signal(signum, handler)

Lib/test/test_curses.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import tempfile
1616
import unittest
1717

18-
from test.support import requires, import_module, verbose
18+
from test.support import requires, import_module, verbose, SaveSignals
1919

2020
# Optionally test curses module. This currently requires that the
2121
# 'curses' resource be given on the regrtest command line using the -u
@@ -63,6 +63,8 @@ def tearDownClass(cls):
6363
del cls.tmp
6464

6565
def setUp(self):
66+
self.save_signals = SaveSignals()
67+
self.save_signals.save()
6668
if verbose:
6769
# just to make the test output a little more readable
6870
print()
@@ -72,6 +74,7 @@ def setUp(self):
7274
def tearDown(self):
7375
curses.resetty()
7476
curses.endwin()
77+
self.save_signals.restore()
7578

7679
def test_window_funcs(self):
7780
"Test the methods of windows"

0 commit comments

Comments
 (0)