Skip to content

Commit e578a9e

Browse files
authored
gh-139156: Use PyBytesWriter in PyUnicode_AsUnicodeEscapeString() (#139249)
Replace PyBytes_FromStringAndSize() and _PyBytes_Resize() with the PyBytesWriter API.
1 parent c863349 commit e578a9e

File tree

1 file changed

+16
-30
lines changed

1 file changed

+16
-30
lines changed

Objects/unicodeobject.c

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6893,46 +6893,36 @@ PyUnicode_DecodeUnicodeEscape(const char *s,
68936893
PyObject *
68946894
PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
68956895
{
6896-
Py_ssize_t i, len;
6897-
PyObject *repr;
6898-
char *p;
6899-
int kind;
6900-
const void *data;
6901-
Py_ssize_t expandsize;
6902-
6903-
/* Initial allocation is based on the longest-possible character
6904-
escape.
6905-
6906-
For UCS1 strings it's '\xxx', 4 bytes per source character.
6907-
For UCS2 strings it's '\uxxxx', 6 bytes per source character.
6908-
For UCS4 strings it's '\U00xxxxxx', 10 bytes per source character.
6909-
*/
6910-
69116896
if (!PyUnicode_Check(unicode)) {
69126897
PyErr_BadArgument();
69136898
return NULL;
69146899
}
69156900

6916-
len = PyUnicode_GET_LENGTH(unicode);
6901+
Py_ssize_t len = PyUnicode_GET_LENGTH(unicode);
69176902
if (len == 0) {
69186903
return Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
69196904
}
6905+
int kind = PyUnicode_KIND(unicode);
6906+
const void *data = PyUnicode_DATA(unicode);
69206907

6921-
kind = PyUnicode_KIND(unicode);
6922-
data = PyUnicode_DATA(unicode);
6923-
/* 4 byte characters can take up 10 bytes, 2 byte characters can take up 6
6924-
bytes, and 1 byte characters 4. */
6925-
expandsize = kind * 2 + 2;
6908+
/* Initial allocation is based on the longest-possible character
6909+
* escape.
6910+
*
6911+
* For UCS1 strings it's '\xxx', 4 bytes per source character.
6912+
* For UCS2 strings it's '\uxxxx', 6 bytes per source character.
6913+
* For UCS4 strings it's '\U00xxxxxx', 10 bytes per source character. */
6914+
Py_ssize_t expandsize = kind * 2 + 2;
69266915
if (len > PY_SSIZE_T_MAX / expandsize) {
69276916
return PyErr_NoMemory();
69286917
}
6929-
repr = PyBytes_FromStringAndSize(NULL, expandsize * len);
6930-
if (repr == NULL) {
6918+
6919+
PyBytesWriter *writer = PyBytesWriter_Create(expandsize * len);
6920+
if (writer == NULL) {
69316921
return NULL;
69326922
}
6923+
char *p = PyBytesWriter_GetData(writer);
69336924

6934-
p = PyBytes_AS_STRING(repr);
6935-
for (i = 0; i < len; i++) {
6925+
for (Py_ssize_t i = 0; i < len; i++) {
69366926
Py_UCS4 ch = PyUnicode_READ(kind, data, i);
69376927

69386928
/* U+0000-U+00ff range */
@@ -6998,11 +6988,7 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
69986988
}
69996989
}
70006990

7001-
assert(p - PyBytes_AS_STRING(repr) > 0);
7002-
if (_PyBytes_Resize(&repr, p - PyBytes_AS_STRING(repr)) < 0) {
7003-
return NULL;
7004-
}
7005-
return repr;
6991+
return PyBytesWriter_FinishWithPointer(writer, p);
70066992
}
70076993

70086994
/* --- Raw Unicode Escape Codec ------------------------------------------- */

0 commit comments

Comments
 (0)