Skip to content

Commit b7dd1b7

Browse files
CPython developersyouknowone
authored andcommitted
Update signal and its test from CPython 3.10.5
1 parent f2ea8e2 commit b7dd1b7

File tree

2 files changed

+55
-11
lines changed

2 files changed

+55
-11
lines changed

Lib/signal.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import _signal
22
from _signal import *
3-
from functools import wraps as _wraps
43
from enum import IntEnum as _IntEnum
54

65
_globals = globals()
@@ -42,6 +41,16 @@ def _enum_to_int(value):
4241
return value
4342

4443

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.
48+
def _wraps(wrapped):
49+
def decorator(wrapper):
50+
wrapper.__doc__ = wrapped.__doc__
51+
return wrapper
52+
return decorator
53+
4554
@_wraps(_signal.signal)
4655
def signal(signalnum, handler):
4756
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
@@ -59,7 +68,6 @@ def getsignal(signalnum):
5968
def pthread_sigmask(how, mask):
6069
sigs_set = _signal.pthread_sigmask(how, mask)
6170
return set(_int_to_enum(x, Signals) for x in sigs_set)
62-
pthread_sigmask.__doc__ = _signal.pthread_sigmask.__doc__
6371

6472

6573
if 'sigpending' in _globals:
@@ -73,7 +81,6 @@ def sigpending():
7381
def sigwait(sigset):
7482
retsig = _signal.sigwait(sigset)
7583
return _int_to_enum(retsig, Signals)
76-
sigwait.__doc__ = _signal.sigwait
7784

7885

7986
if 'valid_signals' in _globals:

Lib/test/test_signal.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import errno
2+
import inspect
23
import os
34
import random
45
import signal
@@ -33,6 +34,14 @@ def test_enums(self):
3334
self.assertIsInstance(sig, signal.Signals)
3435
self.assertEqual(sys.platform, "win32")
3536

37+
def test_functions_module_attr(self):
38+
# Issue #27718: If __all__ is not defined all non-builtin functions
39+
# should have correct __module__ to be displayed by pydoc.
40+
for name in dir(signal):
41+
value = getattr(signal, name)
42+
if inspect.isroutine(value) and not inspect.isbuiltin(value):
43+
self.assertEqual(value.__module__, 'signal')
44+
3645

3746
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
3847
class PosixTests(unittest.TestCase):
@@ -552,16 +561,20 @@ def handler(signum, frame):
552561
else:
553562
write.setblocking(False)
554563
555-
# Start with large chunk size to reduce the
556-
# number of send needed to fill the buffer.
557564
written = 0
558-
for chunk_size in (2 ** 16, 2 ** 8, 1):
565+
if sys.platform == "vxworks":
566+
CHUNK_SIZES = (1,)
567+
else:
568+
# Start with large chunk size to reduce the
569+
# number of send needed to fill the buffer.
570+
CHUNK_SIZES = (2 ** 16, 2 ** 8, 1)
571+
for chunk_size in CHUNK_SIZES:
559572
chunk = b"x" * chunk_size
560573
try:
561574
while True:
562575
write.send(chunk)
563576
written += chunk_size
564-
except (BlockingIOError, socket.timeout):
577+
except (BlockingIOError, TimeoutError):
565578
pass
566579
567580
print(f"%s bytes written into the socketpair" % written, flush=True)
@@ -628,6 +641,7 @@ def handler(signum, frame):
628641

629642

630643
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
644+
@unittest.skipUnless(hasattr(signal, 'siginterrupt'), "needs signal.siginterrupt()")
631645
class SiginterruptTest(unittest.TestCase):
632646

633647
def readpipe_interrupted(self, interrupt):
@@ -678,7 +692,7 @@ def handler(signum, frame):
678692
# wait until the child process is loaded and has started
679693
first_line = process.stdout.readline()
680694

681-
stdout, stderr = process.communicate(timeout=5.0)
695+
stdout, stderr = process.communicate(timeout=support.SHORT_TIMEOUT)
682696
except subprocess.TimeoutExpired:
683697
process.kill()
684698
return False
@@ -717,6 +731,8 @@ def test_siginterrupt_off(self):
717731

718732

719733
@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
734+
@unittest.skipUnless(hasattr(signal, 'getitimer') and hasattr(signal, 'setitimer'),
735+
"needs signal.getitimer() and signal.setitimer()")
720736
class ItimerTest(unittest.TestCase):
721737
def setUp(self):
722738
self.hndl_called = False
@@ -1240,7 +1256,7 @@ def second_handler(signum=None, frame=None):
12401256
self.setsig(signal.SIGALRM, second_handler) # for ITIMER_REAL
12411257

12421258
expected_sigs = 0
1243-
deadline = time.monotonic() + 15.0
1259+
deadline = time.monotonic() + support.SHORT_TIMEOUT
12441260

12451261
while expected_sigs < N:
12461262
os.kill(os.getpid(), signal.SIGPROF)
@@ -1274,7 +1290,7 @@ def handler(signum, frame):
12741290
self.setsig(signal.SIGALRM, handler) # for ITIMER_REAL
12751291

12761292
expected_sigs = 0
1277-
deadline = time.monotonic() + 15.0
1293+
deadline = time.monotonic() + support.SHORT_TIMEOUT
12781294

12791295
while expected_sigs < N:
12801296
# Hopefully the SIGALRM will be received somewhere during
@@ -1336,7 +1352,7 @@ def cycle_handlers():
13361352
# race condition, check it.
13371353
self.assertIsInstance(cm.unraisable.exc_value, OSError)
13381354
self.assertIn(
1339-
f"Signal {signum} ignored due to race condition",
1355+
f"Signal {signum:d} ignored due to race condition",
13401356
str(cm.unraisable.exc_value))
13411357
ignored = True
13421358

@@ -1387,6 +1403,27 @@ def handler(a, b):
13871403
self.assertTrue(is_ok)
13881404

13891405

1406+
class PidfdSignalTest(unittest.TestCase):
1407+
1408+
@unittest.skipUnless(
1409+
hasattr(signal, "pidfd_send_signal"),
1410+
"pidfd support not built in",
1411+
)
1412+
def test_pidfd_send_signal(self):
1413+
with self.assertRaises(OSError) as cm:
1414+
signal.pidfd_send_signal(0, signal.SIGINT)
1415+
if cm.exception.errno == errno.ENOSYS:
1416+
self.skipTest("kernel does not support pidfds")
1417+
elif cm.exception.errno == errno.EPERM:
1418+
self.skipTest("Not enough privileges to use pidfs")
1419+
self.assertEqual(cm.exception.errno, errno.EBADF)
1420+
my_pidfd = os.open(f'/proc/{os.getpid()}', os.O_DIRECTORY)
1421+
self.addCleanup(os.close, my_pidfd)
1422+
with self.assertRaisesRegex(TypeError, "^siginfo must be None$"):
1423+
signal.pidfd_send_signal(my_pidfd, signal.SIGINT, object(), 0)
1424+
with self.assertRaises(KeyboardInterrupt):
1425+
signal.pidfd_send_signal(my_pidfd, signal.SIGINT)
1426+
13901427
def tearDownModule():
13911428
support.reap_children()
13921429

0 commit comments

Comments
 (0)