@@ -236,6 +236,7 @@ def test_readinto(self):
236236 fobj .flush ()
237237 fd = fobj .fileno ()
238238 os .lseek (fd , 0 , 0 )
239+ # Oversized so readinto without hitting end.
239240 buffer = bytearray (7 )
240241 s = os .readinto (fd , buffer )
241242 self .assertEqual (type (s ), int )
@@ -260,23 +261,61 @@ def test_readinto(self):
260261 os .lseek (fd , 0 , 0 )
261262 self .assertEqual (os .readinto (fd , bytearray ()), 0 )
262263
263- def test_readinto_badbuffer (self ):
264+ @unittest .skipUnless (hasattr (os , 'get_blocking' ),
265+ 'needs os.get_blocking() and os.set_blocking()' )
266+ @unittest .skipUnless (hasattr (os , "pipe" ), "requires os.pipe()" )
267+ def test_readinto_non_blocking (self ):
268+ # Verify behavior of a readinto which would block on a non-blocking fd.
269+ r , w = os .pipe ()
270+ try :
271+ os .set_blocking (r , False )
272+ with self .assertRaises (BlockingIOError ):
273+ os .readinto (r , bytearray (5 ))
274+
275+ # Pass some data through
276+ os .write (w , b"spam" )
277+ self .assertEqual (os .readinto (r , bytearray (4 )), 4 )
278+
279+ # Still don't block or return 0.
280+ with self .assertRaises (BlockingIOError ):
281+ os .readinto (r , bytearray (5 ))
282+
283+ # At EOF should return size 0
284+ os .close (w )
285+ w = None
286+ self .assertEqual (os .readinto (r , bytearray (5 )), 0 )
287+ self .assertEqual (os .readinto (r , bytearray (5 )), 0 ) # Still EOF
288+
289+ finally :
290+ os .close (r )
291+ if w is not None :
292+ os .close (w )
293+
294+ def test_readinto_badarg (self ):
264295 with open (os_helper .TESTFN , "w+b" ) as fobj :
265296 fobj .write (b"spam" )
266297 fobj .flush ()
267298 fd = fobj .fileno ()
268299 os .lseek (fd , 0 , 0 )
269300
270301 for bad_arg in ("test" , bytes (), 14 ):
271- with self .subTest (f"{ type (bad_arg )} " ):
302+ with self .subTest (f"bad buffer { type (bad_arg )} " ):
272303 with self .assertRaises (TypeError ):
273304 os .readinto (fd , bad_arg )
274305
306+ with self .subTest ("doesn't work on file objects" ):
307+ with self .assertRaises (TypeError ):
308+ os .readinto (fobj , bytearray (5 ))
309+
310+ # takes two args
311+ with self .assertRaises (TypeError ):
312+ os .readinto (fd )
313+
275314 # No data should have been read with the bad arguments.
276- buffer = bytearray (8 )
315+ buffer = bytearray (4 )
277316 s = os .readinto (fd , buffer )
278317 self .assertEqual (s , 4 )
279- self .assertEqual (bytes ( buffer ) , b"spam\0 \0 \0 \0 " )
318+ self .assertEqual (buffer , b"spam" )
280319
281320 @support .cpython_only
282321 # Skip the test on 32-bit platforms: the number of bytes must fit in a
0 commit comments