https://github.com/python/cpython/commit/3c29fb297478a3379093b1a01550ad274083e38a
commit: 3c29fb297478a3379093b1a01550ad274083e38a
branch: 3.13
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-04-21T07:10:31Z
summary:
[3.13] gh-132753: Argument Clinic: Fix support of c_default for the bool
converter (GH-132754) (GH-132766)
(cherry picked from commit 78cfee6f0920ac914ed179c013f61c53ede16fa9)
files:
M Lib/test/test_clinic.py
M Modules/_testclinic.c
M Modules/clinic/_testclinic.c.h
M Tools/clinic/libclinic/converters.py
diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index e210103a80f399..c3c566d4b332c4 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -3023,6 +3023,11 @@ def test_bool_converter(self):
self.assertEqual(ac_tester.bool_converter('', [], 5), (False, False,
True))
self.assertEqual(ac_tester.bool_converter(('not empty',), {1: 2}, 0),
(True, True, False))
+ def test_bool_converter_c_default(self):
+ self.assertEqual(ac_tester.bool_converter_c_default(), (1, 0, -2, -3))
+ self.assertEqual(ac_tester.bool_converter_c_default(False, True,
False, True),
+ (0, 1, 0, 1))
+
def test_char_converter(self):
with self.assertRaises(TypeError):
ac_tester.char_converter(1)
diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c
index 2dae8accf01182..c352710cf4558d 100644
--- a/Modules/_testclinic.c
+++ b/Modules/_testclinic.c
@@ -209,6 +209,25 @@ bool_converter_impl(PyObject *module, int a, int b, int c)
}
+/*[clinic input]
+bool_converter_c_default
+
+ a: bool = True
+ b: bool = False
+ c: bool(c_default="-2") = True
+ d: bool(c_default="-3") = x
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+bool_converter_c_default_impl(PyObject *module, int a, int b, int c, int d)
+/*[clinic end generated code: output=cf204382e1e4c30c input=185786302ab84081]*/
+{
+ return Py_BuildValue("iiii", a, b, c, d);
+}
+
+
/*[clinic input]
char_converter
@@ -1888,6 +1907,7 @@ static PyMethodDef tester_methods[] = {
BYTE_ARRAY_OBJECT_CONVERTER_METHODDEF
UNICODE_CONVERTER_METHODDEF
BOOL_CONVERTER_METHODDEF
+ BOOL_CONVERTER_C_DEFAULT_METHODDEF
CHAR_CONVERTER_METHODDEF
UNSIGNED_CHAR_CONVERTER_METHODDEF
SHORT_CONVERTER_METHODDEF
diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h
index 1255319357f8fc..63cef8aac43db6 100644
--- a/Modules/clinic/_testclinic.c.h
+++ b/Modules/clinic/_testclinic.c.h
@@ -194,6 +194,64 @@ bool_converter(PyObject *module, PyObject *const *args,
Py_ssize_t nargs)
return return_value;
}
+PyDoc_STRVAR(bool_converter_c_default__doc__,
+"bool_converter_c_default($module, a=True, b=False, c=True, d=x, /)\n"
+"--\n"
+"\n");
+
+#define BOOL_CONVERTER_C_DEFAULT_METHODDEF \
+ {"bool_converter_c_default", _PyCFunction_CAST(bool_converter_c_default),
METH_FASTCALL, bool_converter_c_default__doc__},
+
+static PyObject *
+bool_converter_c_default_impl(PyObject *module, int a, int b, int c, int d);
+
+static PyObject *
+bool_converter_c_default(PyObject *module, PyObject *const *args, Py_ssize_t
nargs)
+{
+ PyObject *return_value = NULL;
+ int a = 1;
+ int b = 0;
+ int c = -2;
+ int d = -3;
+
+ if (!_PyArg_CheckPositional("bool_converter_c_default", nargs, 0, 4)) {
+ goto exit;
+ }
+ if (nargs < 1) {
+ goto skip_optional;
+ }
+ a = PyObject_IsTrue(args[0]);
+ if (a < 0) {
+ goto exit;
+ }
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ b = PyObject_IsTrue(args[1]);
+ if (b < 0) {
+ goto exit;
+ }
+ if (nargs < 3) {
+ goto skip_optional;
+ }
+ c = PyObject_IsTrue(args[2]);
+ if (c < 0) {
+ goto exit;
+ }
+ if (nargs < 4) {
+ goto skip_optional;
+ }
+ d = PyObject_IsTrue(args[3]);
+ if (d < 0) {
+ goto exit;
+ }
+skip_optional:
+ return_value = bool_converter_c_default_impl(module, a, b, c, d);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(char_converter__doc__,
"char_converter($module, a=b\'A\', b=b\'\\x07\', c=b\'\\x08\', d=b\'\\t\',
e=b\'\\n\',\n"
" f=b\'\\x0b\', g=b\'\\x0c\', h=b\'\\r\', i=b\'\"\', j=b\"\'\",
k=b\'?\',\n"
@@ -3327,4 +3385,4 @@ _testclinic_TestClass_get_defining_class_arg(PyObject
*self, PyTypeObject *cls,
exit:
return return_value;
}
-/*[clinic end generated code: output=52b0a0d6e5c291f1 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=c556818496a3ec72 input=a9049054013a1b77]*/
diff --git a/Tools/clinic/libclinic/converters.py
b/Tools/clinic/libclinic/converters.py
index 0778961f5b5875..978bd94fd1304d 100644
--- a/Tools/clinic/libclinic/converters.py
+++ b/Tools/clinic/libclinic/converters.py
@@ -30,7 +30,8 @@ def converter_init(self, *, accept: TypeSet = {object}) ->
None:
fail(f"bool_converter: illegal 'accept' argument {accept!r}")
if self.default is not unspecified and self.default is not unknown:
self.default = bool(self.default)
- self.c_default = str(int(self.default))
+ if self.c_default in {'Py_True', 'Py_False'}:
+ self.c_default = str(int(self.default))
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool)
-> str | None:
if self.format_unit == 'i':
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]