@@ -836,6 +836,11 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
836
836
if (v == NULL )
837
837
goto error ;
838
838
839
+ if (fmtcnt == 0 ) {
840
+ /* last write: disable writer overallocation */
841
+ writer -> overallocate = 0 ;
842
+ }
843
+
839
844
sign = 0 ;
840
845
fill = ' ' ;
841
846
switch (c ) {
@@ -1056,6 +1061,10 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
1056
1061
assert ((res - before ) == alloc );
1057
1062
#endif
1058
1063
} /* '%' */
1064
+
1065
+ /* If overallocation was disabled, ensure that it was the last
1066
+ write. Otherwise, we missed an optimization */
1067
+ assert (writer -> overallocate || fmtcnt == 0 || use_bytearray );
1059
1068
} /* until end */
1060
1069
1061
1070
if (argidx < arglen && !dict ) {
@@ -3746,14 +3755,6 @@ _PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
3746
3755
3747
3756
// --- PyBytesWriter API -----------------------------------------------------
3748
3757
3749
- struct PyBytesWriter {
3750
- char small_buffer [256 ];
3751
- PyObject * obj ;
3752
- Py_ssize_t size ;
3753
- int use_bytearray ;
3754
- };
3755
-
3756
-
3757
3758
static inline char *
3758
3759
byteswriter_data (PyBytesWriter * writer )
3759
3760
{
@@ -3802,7 +3803,8 @@ byteswriter_resize(PyBytesWriter *writer, Py_ssize_t size, int overallocate)
3802
3803
return 0 ;
3803
3804
}
3804
3805
3805
- if (overallocate && !writer -> use_bytearray ) {
3806
+ overallocate &= writer -> overallocate ;
3807
+ if (overallocate ) {
3806
3808
if (size <= (PY_SSIZE_T_MAX - size / OVERALLOCATE_FACTOR )) {
3807
3809
size += size / OVERALLOCATE_FACTOR ;
3808
3810
}
@@ -3867,6 +3869,7 @@ byteswriter_create(Py_ssize_t size, int use_bytearray)
3867
3869
writer -> obj = NULL ;
3868
3870
writer -> size = 0 ;
3869
3871
writer -> use_bytearray = use_bytearray ;
3872
+ writer -> overallocate = !use_bytearray ;
3870
3873
3871
3874
if (size >= 1 ) {
3872
3875
if (byteswriter_resize (writer , size , 0 ) < 0 ) {
0 commit comments