1313import time
1414import unittest
1515from test import support
16+ from test .support import isolation
1617from test .support import (
1718 force_not_colorized , is_apple , is_apple_mobile , os_helper , threading_helper
1819)
@@ -312,59 +313,51 @@ def test_set_wakeup_fd_blocking(self):
312313
313314@unittest .skipIf (sys .platform == "win32" , "Not valid on Windows" )
314315class WakeupSignalTests (unittest .TestCase ):
315- @unittest .skipIf (_testcapi is None , 'need _testcapi' )
316- def check_wakeup (self , test_body , * signals , ordered = True ):
317- # use a subprocess to have only one thread
318- code = """if 1:
319- import _testcapi
320- import os
321- import signal
316+ def check_wakeup (self , test , * signals , ordered = True ):
317+ # The caller is decorated with @runInSubprocess(), so this runs in a fresh
318+ # subprocess that has only one thread for the signal to be delivered to.
322319 import struct
323320
324- signals = {!r}
321+ signals = tuple ( int ( s ) for s in signals )
325322
326323 def handler (signum , frame ):
327324 pass
328325
329- def check_signum(signals):
330- data = os.read(read, len(signals)+1)
331- raised = struct.unpack('%uB' % len(data), data)
332- if not {!r}:
333- raised = set(raised)
334- signals = set(signals)
335- if raised != signals:
336- raise Exception("%r != %r" % (raised, signals))
337-
338- {}
339-
340326 signal .signal (signal .SIGALRM , handler )
341327 read , write = os .pipe ()
342328 os .set_blocking (write , False )
343329 signal .set_wakeup_fd (write )
344330
345- test()
346- check_signum(signals)
331+ test (read )
332+
333+ data = os .read (read , len (signals ) + 1 )
334+ raised = struct .unpack ('%uB' % len (data ), data )
335+ if ordered :
336+ self .assertEqual (raised , signals )
337+ else :
338+ self .assertEqual (set (raised ), set (signals ))
347339
348340 os .close (read )
349341 os .close (write )
350- """ .format (tuple (map (int , signals )), ordered , test_body )
351-
352- assert_python_ok ('-c' , code )
353342
354343 @unittest .skipIf (_testcapi is None , 'need _testcapi' )
355344 @unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
356345 @force_not_colorized
346+ @isolation .runInSubprocess ()
357347 def test_wakeup_write_error (self ):
358348 # Issue #16105: write() errors in the C signal handler should not
359349 # pass silently.
360- # Use a subprocess to have only one thread.
361- code = """if 1:
362- import _testcapi
363- import errno
364- import os
365- import signal
366- import sys
367- from test.support import captured_stderr
350+ # Use @runInSubprocess() to run in a subprocess with only one thread.
351+ r , w = os .pipe ()
352+ try :
353+ os .write (r , b'x' )
354+ except OSError :
355+ pass
356+ else :
357+ self .skipTest ("OS doesn't report write() error on the read end of a pipe" )
358+ finally :
359+ os .close (r )
360+ os .close (w )
368361
369362 def handler (signum , frame ):
370363 1 / 0
@@ -375,38 +368,23 @@ def handler(signum, frame):
375368
376369 # Set wakeup_fd a read-only file descriptor to trigger the error
377370 signal .set_wakeup_fd (r )
378- try :
379- with captured_stderr() as err :
371+ with support . captured_stderr () as err :
372+ with self . assertRaises ( ZeroDivisionError ) :
380373 signal .raise_signal (signal .SIGALRM )
381- except ZeroDivisionError:
382- # An ignored exception should have been printed out on stderr
383- err = err.getvalue()
384- if ('Exception ignored while trying to write to the signal wakeup fd'
385- not in err):
386- raise AssertionError(err)
387- if ('OSError: [Errno %d]' % errno.EBADF) not in err:
388- raise AssertionError(err)
389- else:
390- raise AssertionError("ZeroDivisionError not raised")
374+ # An ignored exception should have been printed out on stderr
375+ err = err .getvalue ()
376+ self .assertIn (
377+ 'Exception ignored while trying to write to the signal wakeup fd' ,
378+ err )
379+ self .assertIn ('OSError: [Errno %d]' % errno .EBADF , err )
391380
392381 os .close (r )
393382 os .close (w )
394- """
395- r , w = os .pipe ()
396- try :
397- os .write (r , b'x' )
398- except OSError :
399- pass
400- else :
401- self .skipTest ("OS doesn't report write() error on the read end of a pipe" )
402- finally :
403- os .close (r )
404- os .close (w )
405-
406- assert_python_ok ('-c' , code )
407383
384+ @unittest .skipIf (_testcapi is None , 'need _testcapi' )
385+ @isolation .runInSubprocess ()
408386 def test_wakeup_fd_early (self ):
409- self . check_wakeup ( """ def test():
387+ def test (read ):
410388 import select
411389 import time
412390
@@ -429,18 +407,19 @@ def handler(signum, frame):
429407 except InterruptSelect :
430408 pass
431409 else :
432- raise Exception ("select() was not interrupted")
410+ self . fail ("select() was not interrupted" )
433411
434412 before_time = time .monotonic ()
435413 select .select ([read ], [], [], TIMEOUT_FULL )
436414 after_time = time .monotonic ()
437415 dt = after_time - before_time
438- if dt >= TIMEOUT_HALF:
439- raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
440- """ , signal .SIGALRM )
416+ self .assertLess (dt , TIMEOUT_HALF )
417+ self .check_wakeup (test , signal .SIGALRM )
441418
419+ @unittest .skipIf (_testcapi is None , 'need _testcapi' )
420+ @isolation .runInSubprocess ()
442421 def test_wakeup_fd_during (self ):
443- self . check_wakeup ( """ def test():
422+ def test (read ):
444423 import select
445424 import time
446425
@@ -462,27 +441,34 @@ def handler(signum, frame):
462441 except InterruptSelect :
463442 pass
464443 else :
465- raise Exception ("select() was not interrupted")
444+ self . fail ("select() was not interrupted" )
466445 after_time = time .monotonic ()
467446 dt = after_time - before_time
468- if dt >= TIMEOUT_HALF:
469- raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
470- """ , signal .SIGALRM )
447+ self .assertLess (dt , TIMEOUT_HALF )
448+ self .check_wakeup (test , signal .SIGALRM )
471449
450+ @unittest .skipIf (_testcapi is None , 'need _testcapi' )
451+ @isolation .runInSubprocess ()
472452 def test_signum (self ):
473- self .check_wakeup ("""def test():
453+ def test (read ):
454+ def handler (signum , frame ):
455+ pass
474456 signal .signal (signal .SIGUSR1 , handler )
475457 signal .raise_signal (signal .SIGUSR1 )
476458 signal .raise_signal (signal .SIGALRM )
477- """ , signal .SIGUSR1 , signal .SIGALRM )
459+ self . check_wakeup ( test , signal .SIGUSR1 , signal .SIGALRM )
478460
479461 @unittest .skipUnless (hasattr (signal , 'pthread_sigmask' ),
480462 'need signal.pthread_sigmask()' )
463+ @unittest .skipIf (_testcapi is None , 'need _testcapi' )
464+ @isolation .runInSubprocess ()
481465 def test_pending (self ):
482- self . check_wakeup ( """ def test():
466+ def test (read ):
483467 signum1 = signal .SIGUSR1
484468 signum2 = signal .SIGUSR2
485469
470+ def handler (signum , frame ):
471+ pass
486472 signal .signal (signum1 , handler )
487473 signal .signal (signum2 , handler )
488474
@@ -491,20 +477,17 @@ def test_pending(self):
491477 signal .raise_signal (signum2 )
492478 # Unblocking the 2 signals calls the C signal handler twice
493479 signal .pthread_sigmask (signal .SIG_UNBLOCK , (signum1 , signum2 ))
494- """ , signal .SIGUSR1 , signal .SIGUSR2 , ordered = False )
480+ self . check_wakeup ( test , signal .SIGUSR1 , signal .SIGUSR2 , ordered = False )
495481
496482
497483@unittest .skipUnless (hasattr (socket , 'socketpair' ), 'need socket.socketpair' )
498484class WakeupSocketSignalTests (unittest .TestCase ):
499485
500486 @unittest .skipIf (_testcapi is None , 'need _testcapi' )
487+ @isolation .runInSubprocess ()
501488 def test_socket (self ):
502- # use a subprocess to have only one thread
503- code = """if 1:
504- import signal
505- import socket
489+ # Use @runInSubprocess() to run in a subprocess with only one thread.
506490 import struct
507- import _testcapi
508491
509492 signum = signal .SIGINT
510493 signals = (signum ,)
@@ -521,33 +504,21 @@ def handler(signum, frame):
521504 signal .raise_signal (signum )
522505
523506 data = read .recv (1 )
524- if not data:
525- raise Exception("no signum written")
507+ self .assertTrue (data , "no signum written" )
526508 raised = struct .unpack ('B' , data )
527- if raised != signals:
528- raise Exception("%r != %r" % (raised, signals))
509+ self .assertEqual (raised , signals )
529510
530511 read .close ()
531512 write .close ()
532- """
533-
534- assert_python_ok ('-c' , code )
535513
536514 @unittest .skipIf (_testcapi is None , 'need _testcapi' )
515+ @isolation .runInSubprocess ()
537516 def test_send_error (self ):
538- # Use a subprocess to have only one thread.
517+ # Use @runInSubprocess() to run in a subprocess with only one thread.
539518 if os .name == 'nt' :
540519 action = 'send'
541520 else :
542521 action = 'write'
543- code = """if 1:
544- import errno
545- import signal
546- import socket
547- import sys
548- import time
549- import _testcapi
550- from test.support import captured_stderr
551522
552523 signum = signal .SIGINT
553524
@@ -566,31 +537,22 @@ def handler(signum, frame):
566537 read .close ()
567538 write .close ()
568539
569- with captured_stderr() as err:
540+ with support . captured_stderr () as err :
570541 signal .raise_signal (signum )
571542
572- err = err.getvalue()
573- if ('Exception ignored while trying to {action} to the signal wakeup fd'
574- not in err):
575- raise AssertionError(err)
576- """ .format (action = action )
577- assert_python_ok ('-c' , code )
543+ self .assertIn (
544+ 'Exception ignored while trying to %s to the signal wakeup fd'
545+ % action ,
546+ err .getvalue ())
578547
579548 @unittest .skipIf (_testcapi is None , 'need _testcapi' )
549+ @isolation .runInSubprocess ()
580550 def test_warn_on_full_buffer (self ):
581- # Use a subprocess to have only one thread.
551+ # Use @runInSubprocess() to run in a subprocess with only one thread.
582552 if os .name == 'nt' :
583553 action = 'send'
584554 else :
585555 action = 'write'
586- code = """if 1:
587- import errno
588- import signal
589- import socket
590- import sys
591- import time
592- import _testcapi
593- from test.support import captured_stderr
594556
595557 signum = signal .SIGINT
596558
@@ -627,67 +589,46 @@ def handler(signum, frame):
627589 except (BlockingIOError , TimeoutError ):
628590 pass
629591
630- print(f"%s bytes written into the socketpair" % written, flush=True)
631-
632592 write .setblocking (False )
633- try:
593+ with self .assertRaises (BlockingIOError ,
594+ msg = "%s bytes failed to fill the socketpair "
595+ "buffer" % written ):
634596 write .send (b"x" )
635- except BlockingIOError:
636- # The socketpair buffer seems full
637- pass
638- else:
639- raise AssertionError("%s bytes failed to fill the socketpair "
640- "buffer" % written)
641597
642598 # By default, we get a warning when a signal arrives
643- msg = ('Exception ignored while trying to {action} '
644- 'to the signal wakeup fd')
599+ msg = ('Exception ignored while trying to %s '
600+ 'to the signal wakeup fd' % action )
645601 signal .set_wakeup_fd (write .fileno ())
646602
647- with captured_stderr() as err:
603+ with support . captured_stderr () as err :
648604 signal .raise_signal (signum )
649-
650- err = err.getvalue()
651- if msg not in err:
652- raise AssertionError("first set_wakeup_fd() test failed, "
653- "stderr: %r" % err)
605+ self .assertIn (msg , err .getvalue (),
606+ "first set_wakeup_fd() test failed" )
654607
655608 # And also if warn_on_full_buffer=True
656609 signal .set_wakeup_fd (write .fileno (), warn_on_full_buffer = True )
657610
658- with captured_stderr() as err:
611+ with support . captured_stderr () as err :
659612 signal .raise_signal (signum )
660-
661- err = err.getvalue()
662- if msg not in err:
663- raise AssertionError("set_wakeup_fd(warn_on_full_buffer=True) "
664- "test failed, stderr: %r" % err)
613+ self .assertIn (msg , err .getvalue (),
614+ "set_wakeup_fd(warn_on_full_buffer=True) test failed" )
665615
666616 # But not if warn_on_full_buffer=False
667617 signal .set_wakeup_fd (write .fileno (), warn_on_full_buffer = False )
668618
669- with captured_stderr() as err:
619+ with support . captured_stderr () as err :
670620 signal .raise_signal (signum )
671-
672- err = err.getvalue()
673- if err != "":
674- raise AssertionError("set_wakeup_fd(warn_on_full_buffer=False) "
675- "test failed, stderr: %r" % err)
621+ self .assertEqual (err .getvalue (), "" ,
622+ "set_wakeup_fd(warn_on_full_buffer=False) test failed" )
676623
677624 # And then check the default again, to make sure warn_on_full_buffer
678625 # settings don't leak across calls.
679626 signal .set_wakeup_fd (write .fileno ())
680627
681- with captured_stderr() as err:
628+ with support . captured_stderr () as err :
682629 signal .raise_signal (signum )
683-
684- err = err.getvalue()
685- if msg not in err:
686- raise AssertionError("second set_wakeup_fd() test failed, "
687- "stderr: %r" % err)
688-
689- """ .format (action = action )
690- assert_python_ok ('-c' , code )
630+ self .assertIn (msg , err .getvalue (),
631+ "second set_wakeup_fd() test failed" )
691632
692633
693634@unittest .skipIf (sys .platform == "win32" , "Not valid on Windows" )
0 commit comments