Skip to content

Commit 51d4bf1

Browse files
authored
bpo-45325: Add a new 'p' parameter to Py_BuildValue to convert an integer into a Python bool (#28634)
1 parent 076300d commit 51d4bf1

File tree

5 files changed

+42
-0
lines changed

5 files changed

+42
-0
lines changed

Doc/c-api/arg.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,10 @@ Building values
645645
``n`` (:class:`int`) [:c:type:`Py_ssize_t`]
646646
Convert a C :c:type:`Py_ssize_t` to a Python integer.
647647
648+
``p`` (:class:`bool`) [int]
649+
Convert a C :c:expr:`int` to a Python :class:`bool` object.
650+
.. versionadded:: 3.14
651+
648652
``c`` (:class:`bytes` of length 1) [char]
649653
Convert a C :c:expr:`int` representing a byte to a Python :class:`bytes` object of
650654
length 1.

Doc/whatsnew/3.14.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,10 @@ New features
14331433
and get an attribute of the module.
14341434
(Contributed by Victor Stinner in :gh:`128911`.)
14351435

1436+
* Add support for a new ``p`` format unit in :c:func:`Py_BuildValue` that allows to
1437+
take a C integer and produce a Python :class:`bool` object. (Contributed by
1438+
Pablo Galindo in :issue:`45325`.)
1439+
14361440

14371441
Limited C API changes
14381442
---------------------
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add a new ``p`` format parameter to :c:func:`Py_BuildValue` that allows to
2+
take a C integer and produce a Python :class:`bool` object. Patch by Pablo
3+
Galindo.

Modules/_testcapimodule.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,31 @@ test_buildvalue_N(PyObject *self, PyObject *Py_UNUSED(ignored))
411411
Py_RETURN_NONE;
412412
}
413413

414+
static PyObject *
415+
test_buildvalue_p(PyObject *self, PyObject *Py_UNUSED(ignored))
416+
{
417+
PyObject *res = Py_BuildValue("p", 3);
418+
if (res == NULL) {
419+
return NULL;
420+
}
421+
if (!Py_IsTrue(res)) {
422+
Py_DECREF(res);
423+
return raiseTestError(self, "test_buildvalue_p", "Py_BuildValue(\"p\", 3) returned wrong result");
424+
}
425+
Py_DECREF(res);
426+
427+
res = Py_BuildValue("p", 0);
428+
if (res == NULL) {
429+
return NULL;
430+
}
431+
if (!Py_IsFalse(res)) {
432+
Py_DECREF(res);
433+
return raiseTestError(self, "test_buildvalue_p", "Py_BuildValue(\"p\", 0) returned wrong result");
434+
}
435+
Py_DECREF(res);
436+
437+
Py_RETURN_NONE;
438+
}
414439

415440
static PyObject *
416441
pyobject_repr_from_null(PyObject *self, PyObject *Py_UNUSED(ignored))
@@ -2512,6 +2537,7 @@ static PyMethodDef TestMethods[] = {
25122537
{"py_buildvalue", py_buildvalue, METH_VARARGS},
25132538
{"py_buildvalue_ints", py_buildvalue_ints, METH_VARARGS},
25142539
{"test_buildvalue_N", test_buildvalue_N, METH_NOARGS},
2540+
{"test_buildvalue_p", test_buildvalue_p, METH_NOARGS},
25152541
{"test_reftracer", test_reftracer, METH_NOARGS},
25162542
{"_test_thread_state", test_thread_state, METH_VARARGS},
25172543
{"gilstate_ensure_release", gilstate_ensure_release, METH_NOARGS},

Python/modsupport.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ do_mkvalue(const char **p_format, va_list *p_va)
364364
int i = va_arg(*p_va, int);
365365
return PyUnicode_FromOrdinal(i);
366366
}
367+
case 'p':
368+
{
369+
int i = va_arg(*p_va, int);
370+
return PyBool_FromLong(i);
371+
}
367372

368373
case 's':
369374
case 'z':

0 commit comments

Comments
 (0)