@@ -59,10 +59,12 @@ def test_fromstringandsize(self):
5959 self .assertEqual (fromstringandsize (b'abc' ), b'abc' )
6060 self .assertEqual (fromstringandsize (b'abc' , 2 ), b'ab' )
6161 self .assertEqual (fromstringandsize (b'abc\0 def' ), b'abc\0 def' )
62- self .assertEqual (fromstringandsize (b'a' ), b'a' )
63- self .assertEqual (fromstringandsize (b'a' , 1 ), b'a' )
64- self .assertEqual (fromstringandsize (b'' , 0 ), b'' )
65- self .assertEqual (fromstringandsize (NULL , 0 ), b'' )
62+
63+ # Return singleton for 0 or 1 bytes
64+ self .assertIs (fromstringandsize (b'' , 0 ), b'' )
65+ self .assertIs (fromstringandsize (NULL , 0 ), b'' )
66+ self .assertIs (fromstringandsize (b'a' , 1 ), b'a' )
67+
6668 self .assertEqual (len (fromstringandsize (NULL , 3 )), 3 )
6769 self .assertRaises ((MemoryError , OverflowError ),
6870 fromstringandsize , NULL , PY_SSIZE_T_MAX )
@@ -77,7 +79,10 @@ def test_fromstring(self):
7779 fromstring = _testlimitedcapi .bytes_fromstring
7880
7981 self .assertEqual (fromstring (b'abc\0 def' ), b'abc' )
80- self .assertEqual (fromstring (b'' ), b'' )
82+
83+ # Return singleton for 0 or 1 bytes
84+ self .assertIs (fromstring (b'' ), b'' )
85+ self .assertIs (fromstring (b'a' ), b'a' )
8186
8287 # CRASHES fromstring(NULL)
8388
@@ -434,7 +439,7 @@ def test_resize(self):
434439 writer = self .create_writer ()
435440 writer .resize (len (b'hello' ))
436441 writer .write (0 , b'hello' )
437- self .assertEqual (writer .finish (), b'hello' )
442+ self .bytes_equal (writer .finish (), b'hello' )
438443
439444 writer = self .create_writer ()
440445 writer .resize (0 ) # noop
@@ -445,7 +450,7 @@ def test_resize(self):
445450 writer .resize (len (b'number=123' ), )
446451 writer .write (len (b'number=' ), b'123' )
447452 writer .resize (len (b'number=123' )) # noop
448- self .assertEqual (writer .finish (), b'number=123' )
453+ self .bytes_equal (writer .finish (), b'number=123' )
449454
450455 # Switch from small buffer to large buffer
451456 writer = self .create_writer ()
@@ -454,7 +459,7 @@ def test_resize(self):
454459 writer .write (0 , b's' * small )
455460 writer .resize (large )
456461 writer .write (small , b'L' * (large - small ))
457- self .assertEqual (writer .finish (),
462+ self .bytes_equal (writer .finish (),
458463 b's' * small + b'L' * (large - small ))
459464
460465 # Make sure that it's possible to write after a resize to zero
@@ -463,7 +468,7 @@ def test_resize(self):
463468 writer .resize (self .LARGE_BUFFER )
464469 writer .resize (0 )
465470 writer .write_bytes (b'abc' , 3 )
466- self .assertEqual (writer .finish (), b'abc' )
471+ self .bytes_equal (writer .finish (), b'abc' )
467472
468473 # invalid size
469474 for size in (self .SMALL_BUFFER , self .LARGE_BUFFER ):
@@ -474,7 +479,7 @@ def test_resize(self):
474479 writer .resize (- 1 )
475480 with self .assertRaises ((MemoryError , OverflowError )):
476481 writer .resize (_testcapi .PY_SSIZE_T_MAX )
477- self .assertEqual (writer .finish (), b'x' * size )
482+ self .bytes_equal (writer .finish (), b'x' * size )
478483
479484 @support .nomemtest
480485 def test_resize_error (self ):
@@ -488,7 +493,7 @@ def test_resize_error(self):
488493 writer .resize (size )
489494 suffix = b'still working'
490495 writer .write_bytes (suffix , - 1 )
491- self .assertEqual (writer .finish (), init + suffix )
496+ self .bytes_equal (writer .finish (), init + suffix )
492497
493498 # Note: PyBytesWriter_Resize() leaves the buffer unchanged (no resize)
494499 # if the new size is smaller than the allocated size
@@ -498,7 +503,7 @@ def test_grow(self):
498503 writer = self .create_writer (0 )
499504 writer .grow (len (b'number=123' ))
500505 writer .write (0 , b'number=123' )
501- self .assertEqual (writer .finish (), b'number=123' )
506+ self .bytes_equal (writer .finish (), b'number=123' )
502507
503508 writer = self .create_writer ()
504509 writer .grow (0 ) # noop
@@ -509,25 +514,7 @@ def test_grow(self):
509514 writer .grow (len (b'123' ), )
510515 writer .write (len (b'number=' ), b'123' )
511516 writer .grow (0 ) # noop
512- self .assertEqual (writer .finish (), b'number=123' )
513-
514- for size in (self .SMALL_BUFFER , self .LARGE_BUFFER ):
515- with self .subTest (size = size ):
516- # Truncate the last byte
517- data = b'x' * size
518- writer = self .create_writer (size )
519- writer .write (0 , data )
520- self .assertEqual (writer .get_data (), data )
521- writer .grow (- 1 )
522- self .assertEqual (writer .get_data (), data [:- 1 ])
523- self .assertEqual (writer .finish (), data [:- 1 ])
524-
525- # Make the buffer empty
526- writer = self .create_writer (size )
527- writer .write (0 , data )
528- writer .grow (- size )
529- self .assertEqual (writer .get_data (), b'' )
530- self .assertEqual (writer .finish (), b'' )
517+ self .bytes_equal (writer .finish (), b'number=123' )
531518
532519 # Switch from small buffer to large buffer
533520 writer = self .create_writer ()
@@ -536,7 +523,7 @@ def test_grow(self):
536523 writer .write (0 , b's' * small )
537524 writer .grow (large - small )
538525 writer .write (small , b'L' * (large - small ))
539- self .assertEqual (writer .finish (),
526+ self .bytes_equal (writer .finish (),
540527 b's' * small + b'L' * (large - small ))
541528
542529 # invalid size
@@ -548,7 +535,7 @@ def test_grow(self):
548535 writer .grow (- size - 1 )
549536 with self .assertRaises (MemoryError ):
550537 writer .grow (_testcapi .PY_SSIZE_T_MAX )
551- self .assertEqual (writer .finish (), b'x' * size )
538+ self .bytes_equal (writer .finish (), b'x' * size )
552539
553540 @support .nomemtest
554541 def test_grow_error (self ):
@@ -574,23 +561,37 @@ def test_format_i(self):
574561
575562 writer = self .create_writer ()
576563 writer .format_i (b'x=%i, ' , 123 )
577- writer .format_i (b'y=%i ' , 456 )
564+ writer .format_i (b'y=%d ' , 456 )
578565 self .bytes_equal (writer .finish (), b'x=123, y=456' )
579566
567+ # Test invalid format: "%t" is invalid, stop the parser and copy
568+ # remaining bytes
569+ writer = self .create_writer ()
570+ writer .write_bytes (b'prefix ' , - 1 )
571+ writer .format_i (b'y=%._ t %i' , 0 )
572+ writer .write_bytes (b'.' , 1 )
573+ self .bytes_equal (writer .finish (), b'prefix y=%._ t %i.' )
574+
580575 def test_format_s (self ):
581576 # Test PyBytesWriter_Format()
582577 writer = self .create_writer ()
583578 writer .format_s (b's=%s' , b'Hello World' )
584579 self .bytes_equal (writer .finish (), b's=Hello World' )
585580
581+ # Test precision
582+ writer = self .create_writer ()
583+ writer .format_s (b'%.6s' , b'Monty Python' )
584+ writer .format_s (b'%.20s' , b'3.0' )
585+ self .bytes_equal (writer .finish (), b'Monty 3.0' )
586+
586587 @support .nomemtest
587588 def test_format_s_memory_error (self ):
588589 writer = self .create_writer ()
589- s = b'x' * 500
590+ s = b'x' * self . LARGE_BUFFER
590591 with self .assertRaises (MemoryError ):
591- with support .inject_memory_error_cm ():
592- writer .format_s (b's=%s' , s )
592+ _testcapi .call_with_nomemory (0 , 0 , writer .format_s , b's=%s' , s )
593593 writer .write_bytes (b'after' , - 1 )
594+ self .bytes_equal (writer .finish (), b'after' )
594595
595596 @threading_helper .requires_working_threading ()
596597 def test_thread (self ):
@@ -620,7 +621,7 @@ def thread_func(writer, LARGE_BUFFER):
620621
621622 self .assertEqual (size , 10 )
622623 self .assertEqual (data , b'x' * 10 )
623- self .assertEqual (writer .finish (), b'x' * 10 )
624+ self .bytes_equal (writer .finish (), b'x' * 10 )
624625
625626
626627class BytesWriterTest (BaseWriterTest , unittest .TestCase ):
0 commit comments