@@ -445,9 +445,6 @@ def test_invalid_operations(self):
445
445
self .assertRaises (exc , fp .seek , 1 , self .SEEK_CUR )
446
446
self .assertRaises (exc , fp .seek , - 1 , self .SEEK_END )
447
447
448
- @unittest .skipIf (
449
- support .is_emscripten , "fstat() of a pipe fd is not supported"
450
- )
451
448
@unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
452
449
def test_optional_abilities (self ):
453
450
# Test for OSError when optional APIs are not supported
@@ -501,57 +498,65 @@ class UnseekableWriter(self.MockUnseekableIO):
501
498
(text_reader , "r" ), (text_writer , "w" ),
502
499
(self .BytesIO , "rws" ), (self .StringIO , "rws" ),
503
500
)
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" )
517
501
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 )
522
507
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" )
529
514
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 )
548
559
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 )
555
560
556
561
def test_open_handles_NUL_chars (self ):
557
562
fn_with_NUL = 'foo\0 bar'
@@ -3927,7 +3932,6 @@ def test_issue35928(self):
3927
3932
self .assertEqual (res + f .readline (), 'foo\n bar\n ' )
3928
3933
3929
3934
@unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
3930
- @unittest .skipIf (support .is_emscripten , "Fixed in next Emscripten release after 4.0.1" )
3931
3935
def test_read_non_blocking (self ):
3932
3936
import os
3933
3937
r , w = os .pipe ()
@@ -4242,9 +4246,6 @@ def test_removed_u_mode(self):
4242
4246
self .open (os_helper .TESTFN , mode )
4243
4247
self .assertIn ('invalid mode' , str (cm .exception ))
4244
4248
4245
- @unittest .skipIf (
4246
- support .is_emscripten , "fstat() of a pipe fd is not supported"
4247
- )
4248
4249
@unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
4249
4250
def test_open_pipe_with_append (self ):
4250
4251
# bpo-27805: Ignore ESPIPE from lseek() in open().
@@ -4413,15 +4414,11 @@ def test_pickling(self):
4413
4414
with self .assertRaisesRegex (TypeError , msg ):
4414
4415
pickle .dumps (f , protocol )
4415
4416
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" )
4419
4418
def test_nonblock_pipe_write_bigbuf (self ):
4420
4419
self ._test_nonblock_pipe_write (16 * 1024 )
4421
4420
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" )
4425
4422
def test_nonblock_pipe_write_smallbuf (self ):
4426
4423
self ._test_nonblock_pipe_write (1024 )
4427
4424
0 commit comments