Skip to content

Commit 89e023e

Browse files
authored
Add PyTuple_FromArray() function (#154)
1 parent 22811c3 commit 89e023e

File tree

4 files changed

+85
-14
lines changed

4 files changed

+85
-14
lines changed

docs/api.rst

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ Latest version of the header file:
2929
Python 3.15
3030
-----------
3131

32+
.. c:function:: PyBytesWriter* PyBytesWriter_Create(Py_ssize_t size)
33+
.. c:function:: void* PyBytesWriter_GetData(PyBytesWriter *writer)
34+
.. c:function:: Py_ssize_t PyBytesWriter_GetSize(PyBytesWriter *writer)
35+
.. c:function:: PyObject* PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
36+
.. c:function:: PyObject* PyBytesWriter_Finish(PyBytesWriter *writer)
37+
.. c:function:: PyObject* PyBytesWriter_FinishWithPointer(PyBytesWriter *writer, void *buf)
38+
.. c:function:: void PyBytesWriter_Discard(PyBytesWriter *writer)
39+
.. c:function:: int PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)
40+
.. c:function:: int PyBytesWriter_Grow(PyBytesWriter *writer, Py_ssize_t size)
41+
.. c:function:: void* PyBytesWriter_GrowAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size, void *buf)
42+
.. c:function:: int PyBytesWriter_WriteBytes(PyBytesWriter *writer, const void *bytes, Py_ssize_t size)
43+
.. c:function:: int PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)
44+
45+
See `PyBytesWriter documentation <https://docs.python.org/dev/c-api/bytes.html#pybyteswriter>`__.
46+
3247
.. c:function:: PyObject* PySys_GetAttr(const char *name)
3348

3449
See `PySys_GetAttr() documentation <https://docs.python.org/dev/c-api/sys.html#c.PySys_GetAttr>`__.
@@ -45,20 +60,9 @@ Python 3.15
4560

4661
See `PySys_GetOptionalAttrString() documentation <https://docs.python.org/dev/c-api/sys.html#c.PySys_GetOptionalAttrString>`__.
4762

48-
.. c:function:: PyBytesWriter* PyBytesWriter_Create(Py_ssize_t size)
49-
.. c:function:: void* PyBytesWriter_GetData(PyBytesWriter *writer)
50-
.. c:function:: Py_ssize_t PyBytesWriter_GetSize(PyBytesWriter *writer)
51-
.. c:function:: PyObject* PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
52-
.. c:function:: PyObject* PyBytesWriter_Finish(PyBytesWriter *writer)
53-
.. c:function:: PyObject* PyBytesWriter_FinishWithPointer(PyBytesWriter *writer, void *buf)
54-
.. c:function:: void PyBytesWriter_Discard(PyBytesWriter *writer)
55-
.. c:function:: int PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)
56-
.. c:function:: int PyBytesWriter_Grow(PyBytesWriter *writer, Py_ssize_t size)
57-
.. c:function:: void* PyBytesWriter_GrowAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size, void *buf)
58-
.. c:function:: int PyBytesWriter_WriteBytes(PyBytesWriter *writer, const void *bytes, Py_ssize_t size)
59-
.. c:function:: int PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)
63+
.. c:function:: PyObject* PyTuple_FromArray(PyObject *const *array, Py_ssize_t size)
6064

61-
See `PyBytesWriter documentation <https://docs.python.org/dev/c-api/bytes.html#pybyteswriter>`__.
65+
See `PyTuple_FromArray() documentation <https://docs.python.org/dev/c-api/tuple.html#c.PyTuple_FromArray>`__.
6266

6367

6468
Python 3.14

docs/changelog.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
Changelog
22
=========
33

4-
* 2025-11-18: Add PEP 782 functions:
4+
* 2025-10-14: Add ``PyTuple_FromArray()`` function.
5+
* 2025-09-18: Add PEP 782 functions:
56

67
* ``PyBytesWriter_Create()``
78
* ``PyBytesWriter_Discard()``

pythoncapi_compat.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,6 +2553,23 @@ PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)
25532553
#endif // PY_VERSION_HEX < 0x030F00A1
25542554

25552555

2556+
#if PY_VERSION_HEX < 0x030F00A1
2557+
static inline PyObject*
2558+
PyTuple_FromArray(PyObject *const *array, Py_ssize_t size)
2559+
{
2560+
PyObject *tuple = PyTuple_New(size);
2561+
if (tuple == NULL) {
2562+
return NULL;
2563+
}
2564+
for (Py_ssize_t i=0; i < size; i++) {
2565+
PyObject *item = array[i];
2566+
PyTuple_SET_ITEM(tuple, i, Py_NewRef(item));
2567+
}
2568+
return tuple;
2569+
}
2570+
#endif
2571+
2572+
25562573
#ifdef __cplusplus
25572574
}
25582575
#endif

tests/test_pythoncapi_compat_cext.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,54 @@ test_byteswriter(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
23922392
}
23932393

23942394

2395+
static PyObject*
2396+
test_tuple_fromarray(void)
2397+
{
2398+
PyObject* array[] = {
2399+
PyLong_FromLong(1),
2400+
PyLong_FromLong(2),
2401+
PyLong_FromLong(3)
2402+
};
2403+
PyObject *tuple = PyTuple_FromArray(array, 3);
2404+
if (tuple == NULL) {
2405+
goto error;
2406+
}
2407+
2408+
assert(PyTuple_GET_SIZE(tuple) == 3);
2409+
assert(PyTuple_GET_ITEM(tuple, 0) == array[0]);
2410+
assert(PyTuple_GET_ITEM(tuple, 1) == array[1]);
2411+
assert(PyTuple_GET_ITEM(tuple, 2) == array[2]);
2412+
2413+
Py_DECREF(tuple);
2414+
Py_DECREF(array[0]);
2415+
Py_DECREF(array[1]);
2416+
Py_DECREF(array[2]);
2417+
2418+
// Test PyTuple_FromArray(NULL, 0)
2419+
tuple = PyTuple_FromArray(NULL, 0);
2420+
if (tuple == NULL) {
2421+
return NULL;
2422+
}
2423+
assert(PyTuple_GET_SIZE(tuple) == 0);
2424+
Py_DECREF(tuple);
2425+
2426+
Py_RETURN_NONE;
2427+
2428+
error:
2429+
Py_DECREF(array[0]);
2430+
Py_DECREF(array[1]);
2431+
Py_DECREF(array[2]);
2432+
return NULL;
2433+
}
2434+
2435+
2436+
static PyObject*
2437+
test_tuple(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
2438+
{
2439+
return test_tuple_fromarray();
2440+
}
2441+
2442+
23952443
static struct PyMethodDef methods[] = {
23962444
{"test_object", test_object, METH_NOARGS, _Py_NULL},
23972445
{"test_py_is", test_py_is, METH_NOARGS, _Py_NULL},
@@ -2446,6 +2494,7 @@ static struct PyMethodDef methods[] = {
24462494
{"test_sys", test_sys, METH_NOARGS, _Py_NULL},
24472495
{"test_uniquely_referenced", test_uniquely_referenced, METH_NOARGS, _Py_NULL},
24482496
{"test_byteswriter", test_byteswriter, METH_NOARGS, _Py_NULL},
2497+
{"test_tuple", test_tuple, METH_NOARGS, _Py_NULL},
24492498
{_Py_NULL, _Py_NULL, 0, _Py_NULL}
24502499
};
24512500

0 commit comments

Comments
 (0)