bpo-45325: Add a new 'p' parameter to Py_BuildValue to convert an integer into a Python bool (#28634)

This commit is contained in:
Pablo Galindo Salgado 2025-02-18 17:14:11 +00:00 committed by GitHub
parent 076300d795
commit 51d4bf1e0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 42 additions and 0 deletions

View file

@ -645,6 +645,10 @@ Building values
``n`` (:class:`int`) [:c:type:`Py_ssize_t`] ``n`` (:class:`int`) [:c:type:`Py_ssize_t`]
Convert a C :c:type:`Py_ssize_t` to a Python integer. Convert a C :c:type:`Py_ssize_t` to a Python integer.
``p`` (:class:`bool`) [int]
Convert a C :c:expr:`int` to a Python :class:`bool` object.
.. versionadded:: 3.14
``c`` (:class:`bytes` of length 1) [char] ``c`` (:class:`bytes` of length 1) [char]
Convert a C :c:expr:`int` representing a byte to a Python :class:`bytes` object of Convert a C :c:expr:`int` representing a byte to a Python :class:`bytes` object of
length 1. length 1.

View file

@ -1433,6 +1433,10 @@ New features
and get an attribute of the module. and get an attribute of the module.
(Contributed by Victor Stinner in :gh:`128911`.) (Contributed by Victor Stinner in :gh:`128911`.)
* Add support for a new ``p`` format unit in :c:func:`Py_BuildValue` that allows to
take a C integer and produce a Python :class:`bool` object. (Contributed by
Pablo Galindo in :issue:`45325`.)
Limited C API changes Limited C API changes
--------------------- ---------------------

View file

@ -0,0 +1,3 @@
Add a new ``p`` format parameter to :c:func:`Py_BuildValue` that allows to
take a C integer and produce a Python :class:`bool` object. Patch by Pablo
Galindo.

View file

@ -411,6 +411,31 @@ test_buildvalue_N(PyObject *self, PyObject *Py_UNUSED(ignored))
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static PyObject *
test_buildvalue_p(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyObject *res = Py_BuildValue("p", 3);
if (res == NULL) {
return NULL;
}
if (!Py_IsTrue(res)) {
Py_DECREF(res);
return raiseTestError(self, "test_buildvalue_p", "Py_BuildValue(\"p\", 3) returned wrong result");
}
Py_DECREF(res);
res = Py_BuildValue("p", 0);
if (res == NULL) {
return NULL;
}
if (!Py_IsFalse(res)) {
Py_DECREF(res);
return raiseTestError(self, "test_buildvalue_p", "Py_BuildValue(\"p\", 0) returned wrong result");
}
Py_DECREF(res);
Py_RETURN_NONE;
}
static PyObject * static PyObject *
pyobject_repr_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) pyobject_repr_from_null(PyObject *self, PyObject *Py_UNUSED(ignored))
@ -2512,6 +2537,7 @@ static PyMethodDef TestMethods[] = {
{"py_buildvalue", py_buildvalue, METH_VARARGS}, {"py_buildvalue", py_buildvalue, METH_VARARGS},
{"py_buildvalue_ints", py_buildvalue_ints, METH_VARARGS}, {"py_buildvalue_ints", py_buildvalue_ints, METH_VARARGS},
{"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS},
{"test_buildvalue_p", test_buildvalue_p, METH_NOARGS},
{"test_reftracer", test_reftracer, METH_NOARGS}, {"test_reftracer", test_reftracer, METH_NOARGS},
{"_test_thread_state", test_thread_state, METH_VARARGS}, {"_test_thread_state", test_thread_state, METH_VARARGS},
{"gilstate_ensure_release", gilstate_ensure_release, METH_NOARGS}, {"gilstate_ensure_release", gilstate_ensure_release, METH_NOARGS},

View file

@ -364,6 +364,11 @@ do_mkvalue(const char **p_format, va_list *p_va)
int i = va_arg(*p_va, int); int i = va_arg(*p_va, int);
return PyUnicode_FromOrdinal(i); return PyUnicode_FromOrdinal(i);
} }
case 'p':
{
int i = va_arg(*p_va, int);
return PyBool_FromLong(i);
}
case 's': case 's':
case 'z': case 'z':