Skip to content

Commit d0b4abe

Browse files
gh-64631: Test exception messages in cloned Argument Clinic funcs (#104167)
1 parent 5245cb6 commit d0b4abe

File tree

3 files changed

+353
-1
lines changed

3 files changed

+353
-1
lines changed

Lib/test/test_clinic.py

+13
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,19 @@ def test_gh_99240_double_free(self):
12841284
with self.assertRaisesRegex(TypeError, expected_error):
12851285
ac_tester.gh_99240_double_free('a', '\0b')
12861286

1287+
def test_cloned_func_exception_message(self):
1288+
incorrect_arg = -1 # f1() and f2() accept a single str
1289+
with self.assertRaisesRegex(TypeError, "clone_f1"):
1290+
ac_tester.clone_f1(incorrect_arg)
1291+
with self.assertRaisesRegex(TypeError, "clone_f2"):
1292+
ac_tester.clone_f2(incorrect_arg)
1293+
1294+
def test_cloned_func_with_converter_exception_message(self):
1295+
for name in "clone_with_conv_f1", "clone_with_conv_f2":
1296+
with self.subTest(name=name):
1297+
func = getattr(ac_tester, name)
1298+
self.assertEqual(func(), name)
1299+
12871300

12881301
if __name__ == "__main__":
12891302
unittest.main()

Modules/_testclinic.c

+81
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@
99

1010
#include "Python.h"
1111

12+
13+
// Used for clone_with_conv_f1 and clone_with_conv_v2
14+
typedef struct {
15+
const char *name;
16+
} custom_t;
17+
18+
static int
19+
custom_converter(PyObject *obj, custom_t *val)
20+
{
21+
return 1;
22+
}
23+
24+
1225
#include "clinic/_testclinic.c.h"
1326

1427

@@ -1117,6 +1130,70 @@ gh_99240_double_free_impl(PyObject *module, char *a, char *b)
11171130
}
11181131

11191132

1133+
/*[clinic input]
1134+
_testclinic.clone_f1 as clone_f1
1135+
path: str
1136+
[clinic start generated code]*/
1137+
1138+
static PyObject *
1139+
clone_f1_impl(PyObject *module, const char *path)
1140+
/*[clinic end generated code: output=8c30b5620ba86715 input=9c614b7f025ebf70]*/
1141+
{
1142+
Py_RETURN_NONE;
1143+
}
1144+
1145+
1146+
/*[clinic input]
1147+
_testclinic.clone_f2 as clone_f2 = _testclinic.clone_f1
1148+
[clinic start generated code]*/
1149+
1150+
static PyObject *
1151+
clone_f2_impl(PyObject *module, const char *path)
1152+
/*[clinic end generated code: output=6aa1c39bec3f5d9b input=1aaaf47d6ed2324a]*/
1153+
{
1154+
Py_RETURN_NONE;
1155+
}
1156+
1157+
1158+
/*[python input]
1159+
class custom_t_converter(CConverter):
1160+
type = 'custom_t'
1161+
converter = 'custom_converter'
1162+
1163+
def pre_render(self):
1164+
self.c_default = f'''{{
1165+
.name = "{self.function.name}",
1166+
}}'''
1167+
1168+
[python start generated code]*/
1169+
/*[python end generated code: output=da39a3ee5e6b4b0d input=b2fb801e99a06bf6]*/
1170+
1171+
1172+
/*[clinic input]
1173+
_testclinic.clone_with_conv_f1 as clone_with_conv_f1
1174+
path: custom_t = None
1175+
[clinic start generated code]*/
1176+
1177+
static PyObject *
1178+
clone_with_conv_f1_impl(PyObject *module, custom_t path)
1179+
/*[clinic end generated code: output=f7e030ffd5439cb0 input=bc77bc80dec3f46d]*/
1180+
{
1181+
return PyUnicode_FromString(path.name);
1182+
}
1183+
1184+
1185+
/*[clinic input]
1186+
_testclinic.clone_with_conv_f2 as clone_with_conv_f2 = _testclinic.clone_with_conv_f1
1187+
[clinic start generated code]*/
1188+
1189+
static PyObject *
1190+
clone_with_conv_f2_impl(PyObject *module, custom_t path)
1191+
/*[clinic end generated code: output=9d7fdd6a75eecee4 input=cff459a205fa83bb]*/
1192+
{
1193+
return PyUnicode_FromString(path.name);
1194+
}
1195+
1196+
11201197
static PyMethodDef tester_methods[] = {
11211198
TEST_EMPTY_FUNCTION_METHODDEF
11221199
OBJECTS_CONVERTER_METHODDEF
@@ -1168,6 +1245,10 @@ static PyMethodDef tester_methods[] = {
11681245
GH_32092_KW_PASS_METHODDEF
11691246
GH_99233_REFCOUNT_METHODDEF
11701247
GH_99240_DOUBLE_FREE_METHODDEF
1248+
CLONE_F1_METHODDEF
1249+
CLONE_F2_METHODDEF
1250+
CLONE_WITH_CONV_F1_METHODDEF
1251+
CLONE_WITH_CONV_F2_METHODDEF
11711252
{NULL, NULL}
11721253
};
11731254

Modules/clinic/_testclinic.c.h

+259-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)