@@ -445,9 +445,6 @@ def test_invalid_operations(self):
445445 self .assertRaises (exc , fp .seek , 1 , self .SEEK_CUR )
446446 self .assertRaises (exc , fp .seek , - 1 , self .SEEK_END )
447447
448- @unittest .skipIf (
449- support .is_emscripten , "fstat() of a pipe fd is not supported"
450- )
451448 @unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
452449 def test_optional_abilities (self ):
453450 # Test for OSError when optional APIs are not supported
@@ -501,57 +498,65 @@ class UnseekableWriter(self.MockUnseekableIO):
501498 (text_reader , "r" ), (text_writer , "w" ),
502499 (self .BytesIO , "rws" ), (self .StringIO , "rws" ),
503500 )
504- for [test , abilities ] in tests :
505- with self .subTest (test ), test () as obj :
506- readable = "r" in abilities
507- self .assertEqual (obj .readable (), readable )
508- writable = "w" in abilities
509- self .assertEqual (obj .writable (), writable )
510-
511- if isinstance (obj , self .TextIOBase ):
512- data = "3"
513- elif isinstance (obj , (self .BufferedIOBase , self .RawIOBase )):
514- data = b"3"
515- else :
516- self .fail ("Unknown base class" )
517501
518- if "f" in abilities :
519- obj .fileno ()
520- else :
521- self .assertRaises (OSError , obj .fileno )
502+ def do_test (test , obj , abilities ):
503+ readable = "r" in abilities
504+ self .assertEqual (obj .readable (), readable )
505+ writable = "w" in abilities
506+ self .assertEqual (obj .writable (), writable )
522507
523- if readable :
524- obj . read ( 1 )
525- obj . read ()
526- else :
527- self . assertRaises ( OSError , obj . read , 1 )
528- self .assertRaises ( OSError , obj . read )
508+ if isinstance ( obj , self . TextIOBase ) :
509+ data = "3"
510+ elif isinstance ( obj , ( self . BufferedIOBase , self . RawIOBase )):
511+ data = b"3"
512+ else :
513+ self .fail ( "Unknown base class" )
529514
530- if writable :
531- obj .write (data )
532- else :
533- self .assertRaises (OSError , obj .write , data )
534-
535- if sys .platform .startswith ("win" ) and test in (
536- pipe_reader , pipe_writer ):
537- # Pipes seem to appear as seekable on Windows
538- continue
539- seekable = "s" in abilities
540- self .assertEqual (obj .seekable (), seekable )
541-
542- if seekable :
543- obj .tell ()
544- obj .seek (0 )
545- else :
546- self .assertRaises (OSError , obj .tell )
547- self .assertRaises (OSError , obj .seek , 0 )
515+ if "f" in abilities :
516+ obj .fileno ()
517+ else :
518+ self .assertRaises (OSError , obj .fileno )
519+
520+ if readable :
521+ obj .read (1 )
522+ obj .read ()
523+ else :
524+ self .assertRaises (OSError , obj .read , 1 )
525+ self .assertRaises (OSError , obj .read )
526+
527+ if writable :
528+ obj .write (data )
529+ else :
530+ self .assertRaises (OSError , obj .write , data )
531+
532+ if sys .platform .startswith ("win" ) and test in (
533+ pipe_reader , pipe_writer ):
534+ # Pipes seem to appear as seekable on Windows
535+ return
536+ seekable = "s" in abilities
537+ self .assertEqual (obj .seekable (), seekable )
538+
539+ if seekable :
540+ obj .tell ()
541+ obj .seek (0 )
542+ else :
543+ self .assertRaises (OSError , obj .tell )
544+ self .assertRaises (OSError , obj .seek , 0 )
545+
546+ if writable and seekable :
547+ obj .truncate ()
548+ obj .truncate (0 )
549+ else :
550+ self .assertRaises (OSError , obj .truncate )
551+ self .assertRaises (OSError , obj .truncate , 0 )
552+
553+ for [test , abilities ] in tests :
554+ with self .subTest (test ):
555+ if test == pipe_writer and not threading_helper .can_start_thread :
556+ skipTest ()
557+ with test () as obj :
558+ do_test (test , obj , abilities )
548559
549- if writable and seekable :
550- obj .truncate ()
551- obj .truncate (0 )
552- else :
553- self .assertRaises (OSError , obj .truncate )
554- self .assertRaises (OSError , obj .truncate , 0 )
555560
556561 def test_open_handles_NUL_chars (self ):
557562 fn_with_NUL = 'foo\0 bar'
@@ -3927,7 +3932,6 @@ def test_issue35928(self):
39273932 self .assertEqual (res + f .readline (), 'foo\n bar\n ' )
39283933
39293934 @unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
3930- @unittest .skipIf (support .is_emscripten , "Fixed in next Emscripten release after 4.0.1" )
39313935 def test_read_non_blocking (self ):
39323936 import os
39333937 r , w = os .pipe ()
@@ -4242,9 +4246,6 @@ def test_removed_u_mode(self):
42424246 self .open (os_helper .TESTFN , mode )
42434247 self .assertIn ('invalid mode' , str (cm .exception ))
42444248
4245- @unittest .skipIf (
4246- support .is_emscripten , "fstat() of a pipe fd is not supported"
4247- )
42484249 @unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
42494250 def test_open_pipe_with_append (self ):
42504251 # bpo-27805: Ignore ESPIPE from lseek() in open().
@@ -4413,15 +4414,11 @@ def test_pickling(self):
44134414 with self .assertRaisesRegex (TypeError , msg ):
44144415 pickle .dumps (f , protocol )
44154416
4416- @unittest .skipIf (
4417- support .is_emscripten , "fstat() of a pipe fd is not supported"
4418- )
4417+ @unittest .skipIf (support .is_emscripten , "Emscripten corrupts memory when writing to nonblocking fd" )
44194418 def test_nonblock_pipe_write_bigbuf (self ):
44204419 self ._test_nonblock_pipe_write (16 * 1024 )
44214420
4422- @unittest .skipIf (
4423- support .is_emscripten , "fstat() of a pipe fd is not supported"
4424- )
4421+ @unittest .skipIf (support .is_emscripten , "Emscripten corrupts memory when writing to nonblocking fd" )
44254422 def test_nonblock_pipe_write_smallbuf (self ):
44264423 self ._test_nonblock_pipe_write (1024 )
44274424
0 commit comments