Skip to content

Commit af386fd

Browse files
authored
gh-129813, PEP 782: Use PyBytesWriter in posix extension (#138829)
Replace PyBytes_FromStringAndSize(NULL, size) and _PyBytes_Resize() with the new public PyBytesWriter API.
1 parent 703da5e commit af386fd

File tree

1 file changed

+36
-59
lines changed

1 file changed

+36
-59
lines changed

Modules/posixmodule.c

Lines changed: 36 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -11507,30 +11507,25 @@ static PyObject *
1150711507
os_read_impl(PyObject *module, int fd, Py_ssize_t length)
1150811508
/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
1150911509
{
11510-
Py_ssize_t n;
11511-
PyObject *buffer;
11512-
1151311510
if (length < 0) {
1151411511
errno = EINVAL;
1151511512
return posix_error();
1151611513
}
1151711514

1151811515
length = Py_MIN(length, _PY_READ_MAX);
1151911516

11520-
buffer = PyBytes_FromStringAndSize((char *)NULL, length);
11521-
if (buffer == NULL)
11517+
PyBytesWriter *writer = PyBytesWriter_Create(length);
11518+
if (writer == NULL) {
1152211519
return NULL;
11520+
}
1152311521

11524-
n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
11522+
Py_ssize_t n = _Py_read(fd, PyBytesWriter_GetData(writer), length);
1152511523
if (n == -1) {
11526-
Py_DECREF(buffer);
11524+
PyBytesWriter_Discard(writer);
1152711525
return NULL;
1152811526
}
1152911527

11530-
if (n != length)
11531-
_PyBytes_Resize(&buffer, n);
11532-
11533-
return buffer;
11528+
return PyBytesWriter_FinishWithSize(writer, n);
1153411529
}
1153511530

1153611531
/*[clinic input]
@@ -11708,20 +11703,20 @@ os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
1170811703
{
1170911704
Py_ssize_t n;
1171011705
int async_err = 0;
11711-
PyObject *buffer;
1171211706

1171311707
if (length < 0) {
1171411708
errno = EINVAL;
1171511709
return posix_error();
1171611710
}
11717-
buffer = PyBytes_FromStringAndSize((char *)NULL, length);
11718-
if (buffer == NULL)
11711+
PyBytesWriter *writer = PyBytesWriter_Create(length);
11712+
if (writer == NULL) {
1171911713
return NULL;
11714+
}
1172011715

1172111716
do {
1172211717
Py_BEGIN_ALLOW_THREADS
1172311718
_Py_BEGIN_SUPPRESS_IPH
11724-
n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
11719+
n = pread(fd, PyBytesWriter_GetData(writer), length, offset);
1172511720
_Py_END_SUPPRESS_IPH
1172611721
Py_END_ALLOW_THREADS
1172711722
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
@@ -11730,12 +11725,10 @@ os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset)
1173011725
if (!async_err) {
1173111726
posix_error();
1173211727
}
11733-
Py_DECREF(buffer);
11728+
PyBytesWriter_Discard(writer);
1173411729
return NULL;
1173511730
}
11736-
if (n != length)
11737-
_PyBytes_Resize(&buffer, n);
11738-
return buffer;
11731+
return PyBytesWriter_FinishWithSize(writer, n);
1173911732
}
1174011733
#endif /* HAVE_PREAD */
1174111734

@@ -14945,29 +14938,26 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
1494514938
int follow_symlinks)
1494614939
/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
1494714940
{
14948-
Py_ssize_t i;
14949-
PyObject *buffer = NULL;
14950-
1495114941
if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
1495214942
return NULL;
1495314943

1495414944
if (PySys_Audit("os.getxattr", "OO", path->object, attribute->object) < 0) {
1495514945
return NULL;
1495614946
}
1495714947

14958-
for (i = 0; ; i++) {
14959-
void *ptr;
14948+
for (Py_ssize_t i = 0; ; i++) {
1496014949
ssize_t result;
1496114950
static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
1496214951
Py_ssize_t buffer_size = buffer_sizes[i];
1496314952
if (!buffer_size) {
1496414953
path_error(path);
1496514954
return NULL;
1496614955
}
14967-
buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
14968-
if (!buffer)
14956+
PyBytesWriter *writer = PyBytesWriter_Create(buffer_size);
14957+
if (writer == NULL) {
1496914958
return NULL;
14970-
ptr = PyBytes_AS_STRING(buffer);
14959+
}
14960+
void *ptr = PyBytesWriter_GetData(writer);
1497114961

1497214962
Py_BEGIN_ALLOW_THREADS;
1497314963
if (path->fd >= 0)
@@ -14979,23 +14969,16 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
1497914969
Py_END_ALLOW_THREADS;
1498014970

1498114971
if (result < 0) {
14972+
PyBytesWriter_Discard(writer);
1498214973
if (errno == ERANGE) {
14983-
Py_DECREF(buffer);
1498414974
continue;
1498514975
}
1498614976
path_error(path);
14987-
Py_DECREF(buffer);
1498814977
return NULL;
1498914978
}
1499014979

14991-
if (result != buffer_size) {
14992-
/* Can only shrink. */
14993-
_PyBytes_Resize(&buffer, result);
14994-
}
14995-
break;
14980+
return PyBytesWriter_FinishWithSize(writer, result);
1499614981
}
14997-
14998-
return buffer;
1499914982
}
1500014983

1500114984

@@ -15222,19 +15205,22 @@ static PyObject *
1522215205
os_urandom_impl(PyObject *module, Py_ssize_t size)
1522315206
/*[clinic end generated code: output=42c5cca9d18068e9 input=58a0def87dbc2c22]*/
1522415207
{
15225-
PyObject *bytes;
15226-
int result;
15208+
if (size < 0) {
15209+
return PyErr_Format(PyExc_ValueError,
15210+
"negative argument not allowed");
15211+
}
1522715212

15228-
bytes = PyBytes_FromStringAndSize(NULL, size);
15229-
if (bytes == NULL)
15213+
PyBytesWriter *writer = PyBytesWriter_Create(size);
15214+
if (writer == NULL) {
1523015215
return NULL;
15216+
}
1523115217

15232-
result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
15218+
int result = _PyOS_URandom(PyBytesWriter_GetData(writer), size);
1523315219
if (result == -1) {
15234-
Py_DECREF(bytes);
15220+
PyBytesWriter_Discard(writer);
1523515221
return NULL;
1523615222
}
15237-
return bytes;
15223+
return PyBytesWriter_Finish(writer);
1523815224
}
1523915225

1524015226
#ifdef HAVE_MEMFD_CREATE
@@ -16704,25 +16690,20 @@ static PyObject *
1670416690
os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
1670516691
/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
1670616692
{
16707-
PyObject *bytes;
16708-
Py_ssize_t n;
16709-
1671016693
if (size < 0) {
1671116694
errno = EINVAL;
1671216695
return posix_error();
1671316696
}
1671416697

16715-
bytes = PyBytes_FromStringAndSize(NULL, size);
16716-
if (bytes == NULL) {
16717-
PyErr_NoMemory();
16698+
PyBytesWriter *writer = PyBytesWriter_Create(size);
16699+
if (writer == NULL) {
1671816700
return NULL;
1671916701
}
16702+
void *data = PyBytesWriter_GetData(writer);
1672016703

16704+
Py_ssize_t n;
1672116705
while (1) {
16722-
n = syscall(SYS_getrandom,
16723-
PyBytes_AS_STRING(bytes),
16724-
PyBytes_GET_SIZE(bytes),
16725-
flags);
16706+
n = syscall(SYS_getrandom, data, size, flags);
1672616707
if (n < 0 && errno == EINTR) {
1672716708
if (PyErr_CheckSignals() < 0) {
1672816709
goto error;
@@ -16739,14 +16720,10 @@ os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
1673916720
goto error;
1674016721
}
1674116722

16742-
if (n != size) {
16743-
_PyBytes_Resize(&bytes, n);
16744-
}
16745-
16746-
return bytes;
16723+
return PyBytesWriter_FinishWithSize(writer, n);
1674716724

1674816725
error:
16749-
Py_DECREF(bytes);
16726+
PyBytesWriter_Discard(writer);
1675016727
return NULL;
1675116728
}
1675216729
#endif /* HAVE_GETRANDOM_SYSCALL */

0 commit comments

Comments
 (0)