@@ -1888,7 +1888,28 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
18881888
18891889 static const char * hexdigit = "0123456789abcdef" ;
18901890
1891- repr = PyString_FromStringAndSize (NULL , 2 + 6 * size + 1 );
1891+ /* Initial allocation is based on the longest-possible unichr
1892+ escape.
1893+
1894+ In wide (UTF-32) builds '\U00xxxxxx' is 10 chars per source
1895+ unichr, so in this case it's the longest unichr escape. In
1896+ narrow (UTF-16) builds this is five chars per source unichr
1897+ since there are two unichrs in the surrogate pair, so in narrow
1898+ (UTF-16) builds it's not the longest unichr escape.
1899+
1900+ In wide or narrow builds '\uxxxx' is 6 chars per source unichr,
1901+ so in the narrow (UTF-16) build case it's the longest unichr
1902+ escape.
1903+ */
1904+
1905+ repr = PyString_FromStringAndSize (NULL ,
1906+ 2
1907+ #ifdef Py_UNICODE_WIDE
1908+ + 10 * size
1909+ #else
1910+ + 6 * size
1911+ #endif
1912+ + 1 );
18921913 if (repr == NULL )
18931914 return NULL ;
18941915
@@ -1913,15 +1934,6 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
19131934#ifdef Py_UNICODE_WIDE
19141935 /* Map 21-bit characters to '\U00xxxxxx' */
19151936 else if (ch >= 0x10000 ) {
1916- int offset = p - PyString_AS_STRING (repr );
1917-
1918- /* Resize the string if necessary */
1919- if (offset + 12 > PyString_GET_SIZE (repr )) {
1920- if (_PyString_Resize (& repr , PyString_GET_SIZE (repr ) + 100 ))
1921- return NULL ;
1922- p = PyString_AS_STRING (repr ) + offset ;
1923- }
1924-
19251937 * p ++ = '\\' ;
19261938 * p ++ = 'U' ;
19271939 * p ++ = hexdigit [(ch >> 28 ) & 0x0000000F ];
@@ -1934,8 +1946,8 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
19341946 * p ++ = hexdigit [ch & 0x0000000F ];
19351947 continue ;
19361948 }
1937- #endif
1938- /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */
1949+ #else
1950+ /* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
19391951 else if (ch >= 0xD800 && ch < 0xDC00 ) {
19401952 Py_UNICODE ch2 ;
19411953 Py_UCS4 ucs ;
@@ -1960,6 +1972,7 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
19601972 s -- ;
19611973 size ++ ;
19621974 }
1975+ #endif
19631976
19641977 /* Map 16-bit characters to '\uxxxx' */
19651978 if (ch >= 256 ) {
0 commit comments