@@ -1609,6 +1609,48 @@ def reader(data):
16091609 self .loop .run_until_complete (proto .done )
16101610 self .assertEqual ('CLOSED' , proto .state )
16111611
1612+ @unittest .skipUnless (sys .platform != 'win32' ,
1613+ "Don't support pipes for Windows" )
1614+ @unittest .skipUnless (hasattr (os , 'mkfifo' ), 'requires os.mkfifo()' )
1615+ def test_write_named_fifo_unread_data (self ):
1616+ # gh-145030: on macOS, the write end of a named FIFO polls as
1617+ # readable while unread data sits in the FIFO, which made the
1618+ # transport misinterpret the event as the reader hanging up
1619+ # and close itself.
1620+ path = os_helper .TESTFN
1621+ os .mkfifo (path )
1622+ self .assertNotEqual (os .stat (path ).st_nlink , 0 )
1623+ self .addCleanup (os_helper .unlink , path )
1624+ rfd = os .open (path , os .O_RDONLY | os .O_NONBLOCK )
1625+ self .addCleanup (os .close , rfd )
1626+ wfd = os .open (path , os .O_WRONLY | os .O_NONBLOCK )
1627+ pipeobj = io .open (wfd , 'wb' , 1024 )
1628+
1629+ proto = MyWritePipeProto (loop = self .loop )
1630+ connect = self .loop .connect_write_pipe (lambda : proto , pipeobj )
1631+ transport , p = self .loop .run_until_complete (connect )
1632+ self .assertIs (p , proto )
1633+ self .assertEqual ('CONNECTED' , proto .state )
1634+
1635+ transport .write (b'1' )
1636+ # Iterate the event loop while the data stays unread in the FIFO;
1637+ # the transport must not detect a false disconnection.
1638+ for _ in range (10 ):
1639+ test_utils .run_briefly (self .loop )
1640+ self .assertEqual ('CONNECTED' , proto .state )
1641+ self .assertFalse (transport .is_closing ())
1642+ self .assertEqual (b'1' , os .read (rfd , 1024 ))
1643+
1644+ transport .write (b'2345' )
1645+ for _ in range (10 ):
1646+ test_utils .run_briefly (self .loop )
1647+ self .assertEqual ('CONNECTED' , proto .state )
1648+ self .assertEqual (b'2345' , os .read (rfd , 1024 ))
1649+
1650+ transport .close ()
1651+ self .loop .run_until_complete (proto .done )
1652+ self .assertEqual ('CLOSED' , proto .state )
1653+
16121654 @unittest .skipUnless (sys .platform != 'win32' ,
16131655 "Don't support pipes for Windows" )
16141656 def test_write_pipe_disconnect_on_close (self ):
0 commit comments