Issue #14705: Add 'p' format character to PyArg_ParseTuple* for bool support.
This commit is contained in:
parent
6b03f2ce45
commit
faf91e75ab
@ -317,6 +317,15 @@ Other objects
|
|||||||
.. versionchanged:: 3.1
|
.. versionchanged:: 3.1
|
||||||
``Py_CLEANUP_SUPPORTED`` was added.
|
``Py_CLEANUP_SUPPORTED`` was added.
|
||||||
|
|
||||||
|
``p`` (:class:`bool`) [int]
|
||||||
|
Tests the value passed in for truth (a boolean **p**\redicate) and converts
|
||||||
|
the result to its equivalent C true/false integer value.
|
||||||
|
Sets the int to 1 if the expression was true and 0 if it was false.
|
||||||
|
This accepts any valid Python value. See :ref:`truth` for more
|
||||||
|
information about how Python tests values for truth.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.3
|
||||||
|
|
||||||
``(items)`` (:class:`tuple`) [*matching-items*]
|
``(items)`` (:class:`tuple`) [*matching-items*]
|
||||||
The object must be a Python sequence whose length is the number of format units
|
The object must be a Python sequence whose length is the number of format units
|
||||||
in *items*. The C arguments must correspond to the individual format units in
|
in *items*. The C arguments must correspond to the individual format units in
|
||||||
|
@ -214,6 +214,36 @@ class LongLong_TestCase(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
|
self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
|
||||||
|
|
||||||
|
class Paradox:
|
||||||
|
"This statement is false."
|
||||||
|
def __bool__(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
class Boolean_TestCase(unittest.TestCase):
|
||||||
|
def test_p(self):
|
||||||
|
from _testcapi import getargs_p
|
||||||
|
self.assertEqual(0, getargs_p(False))
|
||||||
|
self.assertEqual(0, getargs_p(None))
|
||||||
|
self.assertEqual(0, getargs_p(0))
|
||||||
|
self.assertEqual(0, getargs_p(0.0))
|
||||||
|
self.assertEqual(0, getargs_p(0j))
|
||||||
|
self.assertEqual(0, getargs_p(''))
|
||||||
|
self.assertEqual(0, getargs_p(()))
|
||||||
|
self.assertEqual(0, getargs_p([]))
|
||||||
|
self.assertEqual(0, getargs_p({}))
|
||||||
|
|
||||||
|
self.assertEqual(1, getargs_p(True))
|
||||||
|
self.assertEqual(1, getargs_p(1))
|
||||||
|
self.assertEqual(1, getargs_p(1.0))
|
||||||
|
self.assertEqual(1, getargs_p(1j))
|
||||||
|
self.assertEqual(1, getargs_p('x'))
|
||||||
|
self.assertEqual(1, getargs_p((1,)))
|
||||||
|
self.assertEqual(1, getargs_p([1]))
|
||||||
|
self.assertEqual(1, getargs_p({1:2}))
|
||||||
|
self.assertEqual(1, getargs_p(unittest.TestCase))
|
||||||
|
|
||||||
|
self.assertRaises(NotImplementedError, getargs_p, Paradox())
|
||||||
|
|
||||||
|
|
||||||
class Tuple_TestCase(unittest.TestCase):
|
class Tuple_TestCase(unittest.TestCase):
|
||||||
def test_tuple(self):
|
def test_tuple(self):
|
||||||
@ -510,6 +540,7 @@ def test_main():
|
|||||||
tests = [
|
tests = [
|
||||||
Signed_TestCase,
|
Signed_TestCase,
|
||||||
Unsigned_TestCase,
|
Unsigned_TestCase,
|
||||||
|
Boolean_TestCase,
|
||||||
Tuple_TestCase,
|
Tuple_TestCase,
|
||||||
Keywords_TestCase,
|
Keywords_TestCase,
|
||||||
KeywordOnly_TestCase,
|
KeywordOnly_TestCase,
|
||||||
|
@ -916,6 +916,15 @@ getargs_n(PyObject *self, PyObject *args)
|
|||||||
return PyLong_FromSsize_t(value);
|
return PyLong_FromSsize_t(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
getargs_p(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
if (!PyArg_ParseTuple(args, "p", &value))
|
||||||
|
return NULL;
|
||||||
|
return PyLong_FromLong(value);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LONG_LONG
|
#ifdef HAVE_LONG_LONG
|
||||||
static PyObject *
|
static PyObject *
|
||||||
getargs_L(PyObject *self, PyObject *args)
|
getargs_L(PyObject *self, PyObject *args)
|
||||||
@ -2439,6 +2448,7 @@ static PyMethodDef TestMethods[] = {
|
|||||||
{"getargs_i", getargs_i, METH_VARARGS},
|
{"getargs_i", getargs_i, METH_VARARGS},
|
||||||
{"getargs_l", getargs_l, METH_VARARGS},
|
{"getargs_l", getargs_l, METH_VARARGS},
|
||||||
{"getargs_n", getargs_n, METH_VARARGS},
|
{"getargs_n", getargs_n, METH_VARARGS},
|
||||||
|
{"getargs_p", getargs_p, METH_VARARGS},
|
||||||
#ifdef HAVE_LONG_LONG
|
#ifdef HAVE_LONG_LONG
|
||||||
{"getargs_L", getargs_L, METH_VARARGS},
|
{"getargs_L", getargs_L, METH_VARARGS},
|
||||||
{"getargs_K", getargs_K, METH_VARARGS},
|
{"getargs_K", getargs_K, METH_VARARGS},
|
||||||
|
@ -814,6 +814,18 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'p': {/* boolean *p*redicate */
|
||||||
|
int *p = va_arg(*p_va, int *);
|
||||||
|
int val = PyObject_IsTrue(arg);
|
||||||
|
if (val > 0)
|
||||||
|
*p = 1;
|
||||||
|
else if (val == 0)
|
||||||
|
*p = 0;
|
||||||
|
else
|
||||||
|
RETURN_ERR_OCCURRED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
|
/* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
|
||||||
need to be cleaned up! */
|
need to be cleaned up! */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user