1111import types
1212import builtins
1313import random
14+ import traceback
1415from test .support import fcmp , TESTFN , unlink , run_unittest , check_warnings
1516from operator import neg
1617try :
17- import pty
18+ import pty , signal
1819except ImportError :
19- pty = None
20+ pty = signal = None
2021
2122
2223class Squares :
@@ -993,7 +994,7 @@ def test_input(self):
993994 fp .close ()
994995 unlink (TESTFN )
995996
996- @unittest .skipUnless (pty , "the pty module isn't available" )
997+ @unittest .skipUnless (pty , "the pty and signal modules must be available" )
997998 def check_input_tty (self , prompt , terminal_input , stdio_encoding = None ):
998999 r , w = os .pipe ()
9991000 try :
@@ -1004,23 +1005,26 @@ def check_input_tty(self, prompt, terminal_input, stdio_encoding=None):
10041005 self .skipTest ("pty.fork() raised {}" .format (e ))
10051006 if pid == 0 :
10061007 # Child
1007- os .close (r )
1008- # Check the error handlers are accounted for
1009- if stdio_encoding :
1010- sys .stdin = io .TextIOWrapper (sys .stdin .detach (),
1011- encoding = stdio_encoding ,
1012- errors = 'surrogateescape' )
1013- sys .stdout = io .TextIOWrapper (sys .stdout .detach (),
1014- encoding = stdio_encoding ,
1015- errors = 'replace' )
1016- with open (w , "w" ) as wpipe :
1017- try :
1008+ try :
1009+ # Make sure we don't get stuck if there's a problem
1010+ signal .alarm (2 )
1011+ os .close (r )
1012+ # Check the error handlers are accounted for
1013+ if stdio_encoding :
1014+ sys .stdin = io .TextIOWrapper (sys .stdin .detach (),
1015+ encoding = stdio_encoding ,
1016+ errors = 'surrogateescape' )
1017+ sys .stdout = io .TextIOWrapper (sys .stdout .detach (),
1018+ encoding = stdio_encoding ,
1019+ errors = 'replace' )
1020+ with open (w , "w" ) as wpipe :
10181021 print ("tty =" , sys .stdin .isatty () and sys .stdout .isatty (), file = wpipe )
10191022 print (ascii (input (prompt )), file = wpipe )
1020- finally :
1021- print (";EOF" , file = wpipe )
1022- # We don't want to return to unittest...
1023- os ._exit (0 )
1023+ except :
1024+ traceback .print_exc ()
1025+ finally :
1026+ # We don't want to return to unittest...
1027+ os ._exit (0 )
10241028 # Parent
10251029 os .close (w )
10261030 os .write (fd , terminal_input + b"\r \n " )
@@ -1029,15 +1033,21 @@ def check_input_tty(self, prompt, terminal_input, stdio_encoding=None):
10291033 lines = []
10301034 while True :
10311035 line = rpipe .readline ().strip ()
1032- if line == ";EOF" :
1036+ if line == "" :
1037+ # The other end was closed => the child exited
10331038 break
10341039 lines .append (line )
1040+ # Check the result was got and corresponds to the user's terminal input
1041+ if len (lines ) != 2 :
1042+ # Something went wrong, try to get at stderr
1043+ with open (fd , "r" , encoding = "ascii" , errors = "ignore" ) as child_output :
1044+ self .fail ("got %d lines in pipe but expected 2, child output was:\n %s"
1045+ % (len (lines ), child_output .read ()))
1046+ os .close (fd )
10351047 # Check we did exercise the GNU readline path
10361048 self .assertIn (lines [0 ], {'tty = True' , 'tty = False' })
10371049 if lines [0 ] != 'tty = True' :
10381050 self .skipTest ("standard IO in should have been a tty" )
1039- # Check the result was got and corresponds to the user's terminal input
1040- self .assertEqual (len (lines ), 2 )
10411051 input_result = eval (lines [1 ]) # ascii() -> eval() roundtrip
10421052 if stdio_encoding :
10431053 expected = terminal_input .decode (stdio_encoding , 'surrogateescape' )
0 commit comments