Skip to content

Commit af2cecc

Browse files
committed
gh-139156: Use PyBytesWriter in PyUnicode_AsUnicodeEscapeString()
Replace PyBytes_FromStringAndSize() and _PyBytes_Resize() with the PyBytesWriter API.
1 parent 4fb338d commit af2cecc

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
@@ -6892,46 +6892,36 @@ PyUnicode_DecodeUnicodeEscape(const char *s,
68926892
PyObject *
68936893
PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
68946894
{
6895-
Py_ssize_t i, len;
6896-
PyObject *repr;
6897-
char *p;
6898-
int kind;
6899-
const void *data;
6900-
Py_ssize_t expandsize;
6901-
6902-
/* Initial allocation is based on the longest-possible character
6903-
escape.
6904-
6905-
For UCS1 strings it's '\xxx', 4 bytes per source character.
6906-
For UCS2 strings it's '\uxxxx', 6 bytes per source character.
6907-
For UCS4 strings it's '\U00xxxxxx', 10 bytes per source character.
6908-
*/
6909-
69106895
if (!PyUnicode_Check(unicode)) {
69116896
PyErr_BadArgument();
69126897
return NULL;
69136898
}
69146899

6915-
len = PyUnicode_GET_LENGTH(unicode);
6900+
Py_ssize_t len = PyUnicode_GET_LENGTH(unicode);
69166901
if (len == 0) {
69176902
return Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
69186903
}
6904+
int kind = PyUnicode_KIND(unicode);
6905+
const void *data = PyUnicode_DATA(unicode);
69196906

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

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

69376927
/* U+0000-U+00ff range */
@@ -6997,11 +6987,7 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
69976987
}
69986988
}
69996989

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

70076993
/* --- Raw Unicode Escape Codec ------------------------------------------- */

0 commit comments

Comments
 (0)