|
1 | 1 | import errno |
| 2 | +import inspect |
2 | 3 | import os |
3 | 4 | import random |
4 | 5 | import signal |
@@ -33,6 +34,14 @@ def test_enums(self): |
33 | 34 | self.assertIsInstance(sig, signal.Signals) |
34 | 35 | self.assertEqual(sys.platform, "win32") |
35 | 36 |
|
| 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 | + |
36 | 45 |
|
37 | 46 | @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") |
38 | 47 | class PosixTests(unittest.TestCase): |
@@ -552,16 +561,20 @@ def handler(signum, frame): |
552 | 561 | else: |
553 | 562 | write.setblocking(False) |
554 | 563 |
|
555 | | - # Start with large chunk size to reduce the |
556 | | - # number of send needed to fill the buffer. |
557 | 564 | 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: |
559 | 572 | chunk = b"x" * chunk_size |
560 | 573 | try: |
561 | 574 | while True: |
562 | 575 | write.send(chunk) |
563 | 576 | written += chunk_size |
564 | | - except (BlockingIOError, socket.timeout): |
| 577 | + except (BlockingIOError, TimeoutError): |
565 | 578 | pass |
566 | 579 |
|
567 | 580 | print(f"%s bytes written into the socketpair" % written, flush=True) |
@@ -628,6 +641,7 @@ def handler(signum, frame): |
628 | 641 |
|
629 | 642 |
|
630 | 643 | @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") |
| 644 | +@unittest.skipUnless(hasattr(signal, 'siginterrupt'), "needs signal.siginterrupt()") |
631 | 645 | class SiginterruptTest(unittest.TestCase): |
632 | 646 |
|
633 | 647 | def readpipe_interrupted(self, interrupt): |
@@ -678,7 +692,7 @@ def handler(signum, frame): |
678 | 692 | # wait until the child process is loaded and has started |
679 | 693 | first_line = process.stdout.readline() |
680 | 694 |
|
681 | | - stdout, stderr = process.communicate(timeout=5.0) |
| 695 | + stdout, stderr = process.communicate(timeout=support.SHORT_TIMEOUT) |
682 | 696 | except subprocess.TimeoutExpired: |
683 | 697 | process.kill() |
684 | 698 | return False |
@@ -717,6 +731,8 @@ def test_siginterrupt_off(self): |
717 | 731 |
|
718 | 732 |
|
719 | 733 | @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()") |
720 | 736 | class ItimerTest(unittest.TestCase): |
721 | 737 | def setUp(self): |
722 | 738 | self.hndl_called = False |
@@ -1240,7 +1256,7 @@ def second_handler(signum=None, frame=None): |
1240 | 1256 | self.setsig(signal.SIGALRM, second_handler) # for ITIMER_REAL |
1241 | 1257 |
|
1242 | 1258 | expected_sigs = 0 |
1243 | | - deadline = time.monotonic() + 15.0 |
| 1259 | + deadline = time.monotonic() + support.SHORT_TIMEOUT |
1244 | 1260 |
|
1245 | 1261 | while expected_sigs < N: |
1246 | 1262 | os.kill(os.getpid(), signal.SIGPROF) |
@@ -1274,7 +1290,7 @@ def handler(signum, frame): |
1274 | 1290 | self.setsig(signal.SIGALRM, handler) # for ITIMER_REAL |
1275 | 1291 |
|
1276 | 1292 | expected_sigs = 0 |
1277 | | - deadline = time.monotonic() + 15.0 |
| 1293 | + deadline = time.monotonic() + support.SHORT_TIMEOUT |
1278 | 1294 |
|
1279 | 1295 | while expected_sigs < N: |
1280 | 1296 | # Hopefully the SIGALRM will be received somewhere during |
@@ -1336,7 +1352,7 @@ def cycle_handlers(): |
1336 | 1352 | # race condition, check it. |
1337 | 1353 | self.assertIsInstance(cm.unraisable.exc_value, OSError) |
1338 | 1354 | self.assertIn( |
1339 | | - f"Signal {signum} ignored due to race condition", |
| 1355 | + f"Signal {signum:d} ignored due to race condition", |
1340 | 1356 | str(cm.unraisable.exc_value)) |
1341 | 1357 | ignored = True |
1342 | 1358 |
|
@@ -1387,6 +1403,27 @@ def handler(a, b): |
1387 | 1403 | self.assertTrue(is_ok) |
1388 | 1404 |
|
1389 | 1405 |
|
| 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 | + |
1390 | 1427 | def tearDownModule(): |
1391 | 1428 | support.reap_children() |
1392 | 1429 |
|
|
0 commit comments