Skip to content

Commit 67cc1cf

Browse files
authored
gh-129813, PEP 782: Use PyBytesWriter in _codecs.escape_decode() (#138919)
Replace PyBytes_FromStringAndSize(NULL, size) and _PyBytes_Resize() with the new public PyBytesWriter API.
1 parent 21c80ca commit 67cc1cf

File tree

1 file changed

+32
-37
lines changed

1 file changed

+32
-37
lines changed

Modules/_codecsmodule.c

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -202,55 +202,50 @@ _codecs_escape_encode_impl(PyObject *module, PyObject *data,
202202
const char *errors)
203203
/*[clinic end generated code: output=4af1d477834bab34 input=8f4b144799a94245]*/
204204
{
205-
Py_ssize_t size;
206-
Py_ssize_t newsize;
207-
PyObject *v;
208-
209-
size = PyBytes_GET_SIZE(data);
205+
Py_ssize_t size = PyBytes_GET_SIZE(data);
210206
if (size > PY_SSIZE_T_MAX / 4) {
211207
PyErr_SetString(PyExc_OverflowError,
212208
"string is too large to encode");
213209
return NULL;
214210
}
215-
newsize = 4*size;
216-
v = PyBytes_FromStringAndSize(NULL, newsize);
211+
Py_ssize_t newsize = 4*size;
217212

218-
if (v == NULL) {
213+
PyBytesWriter *writer = PyBytesWriter_Create(newsize);
214+
if (writer == NULL) {
219215
return NULL;
220216
}
221-
else {
222-
Py_ssize_t i;
223-
char c;
224-
char *p = PyBytes_AS_STRING(v);
225-
226-
for (i = 0; i < size; i++) {
227-
/* There's at least enough room for a hex escape */
228-
assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4);
229-
c = PyBytes_AS_STRING(data)[i];
230-
if (c == '\'' || c == '\\')
231-
*p++ = '\\', *p++ = c;
232-
else if (c == '\t')
233-
*p++ = '\\', *p++ = 't';
234-
else if (c == '\n')
235-
*p++ = '\\', *p++ = 'n';
236-
else if (c == '\r')
237-
*p++ = '\\', *p++ = 'r';
238-
else if (c < ' ' || c >= 0x7f) {
239-
*p++ = '\\';
240-
*p++ = 'x';
241-
*p++ = Py_hexdigits[(c & 0xf0) >> 4];
242-
*p++ = Py_hexdigits[c & 0xf];
243-
}
244-
else
245-
*p++ = c;
217+
char *p = PyBytesWriter_GetData(writer);
218+
219+
for (Py_ssize_t i = 0; i < size; i++) {
220+
/* There's at least enough room for a hex escape */
221+
assert(newsize - (p - (char*)PyBytesWriter_GetData(writer)) >= 4);
222+
223+
char c = PyBytes_AS_STRING(data)[i];
224+
if (c == '\'' || c == '\\') {
225+
*p++ = '\\'; *p++ = c;
246226
}
247-
*p = '\0';
248-
if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) {
249-
return NULL;
227+
else if (c == '\t') {
228+
*p++ = '\\'; *p++ = 't';
229+
}
230+
else if (c == '\n') {
231+
*p++ = '\\'; *p++ = 'n';
232+
}
233+
else if (c == '\r') {
234+
*p++ = '\\'; *p++ = 'r';
235+
}
236+
else if (c < ' ' || c >= 0x7f) {
237+
*p++ = '\\';
238+
*p++ = 'x';
239+
*p++ = Py_hexdigits[(c & 0xf0) >> 4];
240+
*p++ = Py_hexdigits[c & 0xf];
241+
}
242+
else {
243+
*p++ = c;
250244
}
251245
}
252246

253-
return codec_tuple(v, size);
247+
PyObject *decoded = PyBytesWriter_FinishWithPointer(writer, p);
248+
return codec_tuple(decoded, size);
254249
}
255250

256251
/* --- Decoder ------------------------------------------------------------ */

0 commit comments

Comments
 (0)