[Python-checkins] cpython: Issue #14705: Add 'p' format character to PyArg_ParseTuple* for bool support.
larry.hastings
python-checkins at python.org
Sun May 6 01:55:38 CEST 2012
http://hg.python.org/cpython/rev/bc6d28e726d8
changeset: 76776:bc6d28e726d8
user: Larry Hastings <larry at hastings.org>
date: Sat May 05 16:54:29 2012 -0700
summary:
Issue #14705: Add 'p' format character to PyArg_ParseTuple* for bool support.
files:
Doc/c-api/arg.rst | 9 +++++++
Lib/test/test_getargs2.py | 31 +++++++++++++++++++++++++++
Modules/_testcapimodule.c | 10 ++++++++
Python/getargs.c | 12 ++++++++++
4 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -317,6 +317,15 @@
.. versionchanged:: 3.1
``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*]
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
diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py
--- a/Lib/test/test_getargs2.py
+++ b/Lib/test/test_getargs2.py
@@ -214,6 +214,36 @@
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):
def test_tuple(self):
@@ -510,6 +540,7 @@
tests = [
Signed_TestCase,
Unsigned_TestCase,
+ Boolean_TestCase,
Tuple_TestCase,
Keywords_TestCase,
KeywordOnly_TestCase,
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -916,6 +916,15 @@
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
static PyObject *
getargs_L(PyObject *self, PyObject *args)
@@ -2439,6 +2448,7 @@
{"getargs_i", getargs_i, METH_VARARGS},
{"getargs_l", getargs_l, METH_VARARGS},
{"getargs_n", getargs_n, METH_VARARGS},
+ {"getargs_p", getargs_p, METH_VARARGS},
#ifdef HAVE_LONG_LONG
{"getargs_L", getargs_L, METH_VARARGS},
{"getargs_K", getargs_K, METH_VARARGS},
diff --git a/Python/getargs.c b/Python/getargs.c
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -814,6 +814,18 @@
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
need to be cleaned up! */
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list