@@ -836,6 +836,11 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
836836 if (v == NULL )
837837 goto error ;
838838
839+ if (fmtcnt == 0 ) {
840+ /* last write: disable writer overallocation */
841+ writer -> overallocate = 0 ;
842+ }
843+
839844 sign = 0 ;
840845 fill = ' ' ;
841846 switch (c ) {
@@ -1056,6 +1061,10 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
10561061 assert ((res - before ) == alloc );
10571062#endif
10581063 } /* '%' */
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 );
10591068 } /* until end */
10601069
10611070 if (argidx < arglen && !dict ) {
@@ -3746,14 +3755,6 @@ _PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
37463755
37473756// --- PyBytesWriter API -----------------------------------------------------
37483757
3749- struct PyBytesWriter {
3750- char small_buffer [256 ];
3751- PyObject * obj ;
3752- Py_ssize_t size ;
3753- int use_bytearray ;
3754- };
3755-
3756-
37573758static inline char *
37583759byteswriter_data (PyBytesWriter * writer )
37593760{
@@ -3802,7 +3803,8 @@ byteswriter_resize(PyBytesWriter *writer, Py_ssize_t size, int overallocate)
38023803 return 0 ;
38033804 }
38043805
3805- if (overallocate && !writer -> use_bytearray ) {
3806+ overallocate &= writer -> overallocate ;
3807+ if (overallocate ) {
38063808 if (size <= (PY_SSIZE_T_MAX - size / OVERALLOCATE_FACTOR )) {
38073809 size += size / OVERALLOCATE_FACTOR ;
38083810 }
@@ -3867,6 +3869,7 @@ byteswriter_create(Py_ssize_t size, int use_bytearray)
38673869 writer -> obj = NULL ;
38683870 writer -> size = 0 ;
38693871 writer -> use_bytearray = use_bytearray ;
3872+ writer -> overallocate = !use_bytearray ;
38703873
38713874 if (size >= 1 ) {
38723875 if (byteswriter_resize (writer , size , 0 ) < 0 ) {
0 commit comments