summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-02-23 15:03:13 (GMT)
committerGitHub <noreply@github.com>2023-02-23 15:03:13 (GMT)
commitefc985a714b6f43c43ae629183f95618054422ae (patch)
tree06d0f62d91e22372a6e75d9ad8061767b9689f95 /Modules
parente07b304bb004e1298283c82bd135dd5ef96a90cc (diff)
downloadcpython-efc985a714b6f43c43ae629183f95618054422ae.zip
cpython-efc985a714b6f43c43ae629183f95618054422ae.tar.gz
cpython-efc985a714b6f43c43ae629183f95618054422ae.tar.bz2
gh-93649: Split exception tests from _testcapimodule.c (GH-102173)
Automerge-Triggered-By: GH:erlend-aasland
Diffstat (limited to 'Modules')
-rw-r--r--Modules/Setup.stdlib.in2
-rw-r--r--Modules/_testcapi/exceptions.c277
-rw-r--r--Modules/_testcapi/parts.h1
-rw-r--r--Modules/_testcapimodule.c290
4 files changed, 282 insertions, 288 deletions
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index d33cd82..7551e5b 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -169,7 +169,7 @@
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
-@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c
+@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
# Some testing modules MUST be built as shared libraries.
diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c
new file mode 100644
index 0000000..43b88cc
--- /dev/null
+++ b/Modules/_testcapi/exceptions.c
@@ -0,0 +1,277 @@
+#include "parts.h"
+
+static PyObject *
+err_set_raised(PyObject *self, PyObject *exc)
+{
+ Py_INCREF(exc);
+ PyErr_SetRaisedException(exc);
+ assert(PyErr_Occurred());
+ return NULL;
+}
+
+static PyObject *
+err_restore(PyObject *self, PyObject *args) {
+ PyObject *type = NULL, *value = NULL, *traceback = NULL;
+ switch(PyTuple_Size(args)) {
+ case 3:
+ traceback = PyTuple_GetItem(args, 2);
+ Py_INCREF(traceback);
+ /* fall through */
+ case 2:
+ value = PyTuple_GetItem(args, 1);
+ Py_INCREF(value);
+ /* fall through */
+ case 1:
+ type = PyTuple_GetItem(args, 0);
+ Py_INCREF(type);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError,
+ "wrong number of arguments");
+ return NULL;
+ }
+ PyErr_Restore(type, value, traceback);
+ assert(PyErr_Occurred());
+ return NULL;
+}
+
+/* To test the format of exceptions as printed out. */
+static PyObject *
+exception_print(PyObject *self, PyObject *args)
+{
+ PyObject *value;
+ PyObject *tb = NULL;
+
+ if (!PyArg_ParseTuple(args, "O:exception_print", &value)) {
+ return NULL;
+ }
+
+ if (PyExceptionInstance_Check(value)) {
+ tb = PyException_GetTraceback(value);
+ }
+
+ PyErr_Display((PyObject *) Py_TYPE(value), value, tb);
+ Py_XDECREF(tb);
+
+ Py_RETURN_NONE;
+}
+
+/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException).
+ Run via Lib/test/test_exceptions.py */
+static PyObject *
+make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ const char *name;
+ const char *doc = NULL;
+ PyObject *base = NULL;
+ PyObject *dict = NULL;
+
+ static char *kwlist[] = {"name", "doc", "base", "dict", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s|sOO:make_exception_with_doc", kwlist,
+ &name, &doc, &base, &dict))
+ {
+ return NULL;
+ }
+
+ return PyErr_NewExceptionWithDoc(name, doc, base, dict);
+}
+
+static PyObject *
+raise_exception(PyObject *self, PyObject *args)
+{
+ PyObject *exc;
+ int num_args;
+
+ if (!PyArg_ParseTuple(args, "Oi:raise_exception", &exc, &num_args)) {
+ return NULL;
+ }
+
+ PyObject *exc_args = PyTuple_New(num_args);
+ if (exc_args == NULL) {
+ return NULL;
+ }
+ for (int i = 0; i < num_args; ++i) {
+ PyObject *v = PyLong_FromLong(i);
+ if (v == NULL) {
+ Py_DECREF(exc_args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(exc_args, i, v);
+ }
+ PyErr_SetObject(exc, exc_args);
+ Py_DECREF(exc_args);
+ return NULL;
+}
+
+/* reliably raise a MemoryError */
+static PyObject *
+raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return PyErr_NoMemory();
+}
+
+static PyObject *
+test_fatal_error(PyObject *self, PyObject *args)
+{
+ char *message;
+ int release_gil = 0;
+ if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) {
+ return NULL;
+ }
+ if (release_gil) {
+ Py_BEGIN_ALLOW_THREADS
+ Py_FatalError(message);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ Py_FatalError(message);
+ }
+ // Py_FatalError() does not return, but exits the process.
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+test_set_exc_info(PyObject *self, PyObject *args)
+{
+ PyObject *new_type, *new_value, *new_tb;
+ PyObject *type, *value, *tb;
+ if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info",
+ &new_type, &new_value, &new_tb))
+ {
+ return NULL;
+ }
+
+ PyErr_GetExcInfo(&type, &value, &tb);
+
+ Py_INCREF(new_type);
+ Py_INCREF(new_value);
+ Py_INCREF(new_tb);
+ PyErr_SetExcInfo(new_type, new_value, new_tb);
+
+ PyObject *orig_exc = PyTuple_Pack(3,
+ type ? type : Py_None,
+ value ? value : Py_None,
+ tb ? tb : Py_None);
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(tb);
+ return orig_exc;
+}
+
+static PyObject *
+test_set_exception(PyObject *self, PyObject *new_exc)
+{
+ PyObject *exc = PyErr_GetHandledException();
+ assert(PyExceptionInstance_Check(exc) || exc == NULL);
+
+ PyErr_SetHandledException(new_exc);
+ return exc;
+}
+
+static PyObject *
+test_write_unraisable_exc(PyObject *self, PyObject *args)
+{
+ PyObject *exc, *err_msg, *obj;
+ if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) {
+ return NULL;
+ }
+
+ const char *err_msg_utf8;
+ if (err_msg != Py_None) {
+ err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
+ if (err_msg_utf8 == NULL) {
+ return NULL;
+ }
+ }
+ else {
+ err_msg_utf8 = NULL;
+ }
+
+ PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
+ _PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
+ Py_RETURN_NONE;
+}
+
+/* To test the format of tracebacks as printed out. */
+static PyObject *
+traceback_print(PyObject *self, PyObject *args)
+{
+ PyObject *file;
+ PyObject *traceback;
+
+ if (!PyArg_ParseTuple(args, "OO:traceback_print",
+ &traceback, &file))
+ {
+ return NULL;
+ }
+
+ if (PyTraceBack_Print(traceback, file) < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+
+/*
+ * Define the PyRecurdingInfinitelyError_Type
+ */
+
+static PyTypeObject PyRecursingInfinitelyError_Type;
+
+static int
+recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
+
+ /* Instantiating this exception starts infinite recursion. */
+ Py_INCREF(type);
+ PyErr_SetObject(type, NULL);
+ return -1;
+}
+
+static PyTypeObject PyRecursingInfinitelyError_Type = {
+ .tp_name = "RecursingInfinitelyError",
+ .tp_basicsize = sizeof(PyBaseExceptionObject),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."),
+ .tp_init = (initproc)recurse_infinitely_error_init,
+};
+
+static PyMethodDef test_methods[] = {
+ {"err_restore", err_restore, METH_VARARGS},
+ {"err_set_raised", err_set_raised, METH_O},
+ {"exception_print", exception_print, METH_VARARGS},
+ {"fatal_error", test_fatal_error, METH_VARARGS,
+ PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
+ {"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
+ METH_VARARGS | METH_KEYWORDS},
+ {"raise_exception", raise_exception, METH_VARARGS},
+ {"raise_memoryerror", raise_memoryerror, METH_NOARGS},
+ {"set_exc_info", test_set_exc_info, METH_VARARGS},
+ {"set_exception", test_set_exception, METH_O},
+ {"traceback_print", traceback_print, METH_VARARGS},
+ {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
+ {NULL},
+};
+
+int
+_PyTestCapi_Init_Exceptions(PyObject *mod)
+{
+ PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
+ if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
+ return -1;
+ }
+ if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError",
+ (PyObject *)&PyRecursingInfinitelyError_Type) < 0)
+ {
+ return -1;
+ }
+
+ if (PyModule_AddFunctions(mod, test_methods) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h
index 7ba3c4e..1689f18 100644
--- a/Modules/_testcapi/parts.h
+++ b/Modules/_testcapi/parts.h
@@ -36,6 +36,7 @@ int _PyTestCapi_Init_Watchers(PyObject *module);
int _PyTestCapi_Init_Long(PyObject *module);
int _PyTestCapi_Init_Float(PyObject *module);
int _PyTestCapi_Init_Structmember(PyObject *module);
+int _PyTestCapi_Init_Exceptions(PyObject *module);
#ifdef LIMITED_API_AVAILABLE
int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index e2237d2..6bb4242 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -721,33 +721,6 @@ pyobject_bytes_from_null(PyObject *self, PyObject *Py_UNUSED(ignored))
}
static PyObject *
-raise_exception(PyObject *self, PyObject *args)
-{
- PyObject *exc;
- PyObject *exc_args, *v;
- int num_args, i;
-
- if (!PyArg_ParseTuple(args, "Oi:raise_exception",
- &exc, &num_args))
- return NULL;
-
- exc_args = PyTuple_New(num_args);
- if (exc_args == NULL)
- return NULL;
- for (i = 0; i < num_args; ++i) {
- v = PyLong_FromLong(i);
- if (v == NULL) {
- Py_DECREF(exc_args);
- return NULL;
- }
- PyTuple_SET_ITEM(exc_args, i, v);
- }
- PyErr_SetObject(exc, exc_args);
- Py_DECREF(exc_args);
- return NULL;
-}
-
-static PyObject *
set_errno(PyObject *self, PyObject *args)
{
int new_errno;
@@ -759,40 +732,6 @@ set_errno(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static PyObject *
-test_set_exception(PyObject *self, PyObject *new_exc)
-{
- PyObject *exc = PyErr_GetHandledException();
- assert(PyExceptionInstance_Check(exc) || exc == NULL);
-
- PyErr_SetHandledException(new_exc);
- return exc;
-}
-
-static PyObject *
-test_set_exc_info(PyObject *self, PyObject *args)
-{
- PyObject *orig_exc;
- PyObject *new_type, *new_value, *new_tb;
- PyObject *type, *value, *tb;
- if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info",
- &new_type, &new_value, &new_tb))
- return NULL;
-
- PyErr_GetExcInfo(&type, &value, &tb);
-
- Py_INCREF(new_type);
- Py_INCREF(new_value);
- Py_INCREF(new_tb);
- PyErr_SetExcInfo(new_type, new_value, new_tb);
-
- orig_exc = PyTuple_Pack(3, type ? type : Py_None, value ? value : Py_None, tb ? tb : Py_None);
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(tb);
- return orig_exc;
-}
-
/* test_thread_state spawns a thread of its own, and that thread releases
* `thread_done` when it's finished. The driver code has to know when the
* thread finishes, because the thread uses a PyObject (the callable) that
@@ -1272,57 +1211,6 @@ profile_int(PyObject *self, PyObject* args)
}
#endif
-/* To test the format of tracebacks as printed out. */
-static PyObject *
-traceback_print(PyObject *self, PyObject *args)
-{
- PyObject *file;
- PyObject *traceback;
- int result;
-
- if (!PyArg_ParseTuple(args, "OO:traceback_print",
- &traceback, &file))
- return NULL;
-
- result = PyTraceBack_Print(traceback, file);
- if (result < 0)
- return NULL;
- Py_RETURN_NONE;
-}
-
-/* To test the format of exceptions as printed out. */
-static PyObject *
-exception_print(PyObject *self, PyObject *args)
-{
- PyObject *value;
- PyObject *tb = NULL;
-
- if (!PyArg_ParseTuple(args, "O:exception_print",
- &value)) {
- return NULL;
- }
-
- if (PyExceptionInstance_Check(value)) {
- tb = PyException_GetTraceback(value);
- }
-
- PyErr_Display((PyObject *) Py_TYPE(value), value, tb);
- Py_XDECREF(tb);
-
- Py_RETURN_NONE;
-}
-
-
-
-
-/* reliably raise a MemoryError */
-static PyObject *
-raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
- PyErr_NoMemory();
- return NULL;
-}
-
/* Issue 6012 */
static PyObject *str1, *str2;
static int
@@ -1368,26 +1256,6 @@ code_newempty(PyObject *self, PyObject *args)
return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno);
}
-/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException).
- Run via Lib/test/test_exceptions.py */
-static PyObject *
-make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- const char *name;
- const char *doc = NULL;
- PyObject *base = NULL;
- PyObject *dict = NULL;
-
- static char *kwlist[] = {"name", "doc", "base", "dict", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "s|sOO:make_exception_with_doc", kwlist,
- &name, &doc, &base, &dict))
- return NULL;
-
- return PyErr_NewExceptionWithDoc(name, doc, base, dict);
-}
-
static PyObject *
make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored))
{
@@ -2491,31 +2359,6 @@ negative_refcount(PyObject *self, PyObject *Py_UNUSED(args))
#endif
-static PyObject*
-test_write_unraisable_exc(PyObject *self, PyObject *args)
-{
- PyObject *exc, *err_msg, *obj;
- if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) {
- return NULL;
- }
-
- const char *err_msg_utf8;
- if (err_msg != Py_None) {
- err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
- if (err_msg_utf8 == NULL) {
- return NULL;
- }
- }
- else {
- err_msg_utf8 = NULL;
- }
-
- PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
- _PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
- Py_RETURN_NONE;
-}
-
-
static PyObject *
sequence_getitem(PyObject *self, PyObject *args)
{
@@ -2874,25 +2717,6 @@ test_py_is_funcs(PyObject *self, PyObject *Py_UNUSED(ignored))
}
-static PyObject *
-test_fatal_error(PyObject *self, PyObject *args)
-{
- char *message;
- int release_gil = 0;
- if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil))
- return NULL;
- if (release_gil) {
- Py_BEGIN_ALLOW_THREADS
- Py_FatalError(message);
- Py_END_ALLOW_THREADS
- }
- else {
- Py_FatalError(message);
- }
- // Py_FatalError() does not return, but exits the process.
- Py_RETURN_NONE;
-}
-
// type->tp_version_tag
static PyObject *
type_get_version(PyObject *self, PyObject *type)
@@ -3492,46 +3316,9 @@ function_set_kw_defaults(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-static PyObject *
-err_set_raised(PyObject *self, PyObject *exc)
-{
- Py_INCREF(exc);
- PyErr_SetRaisedException(exc);
- assert(PyErr_Occurred());
- return NULL;
-}
-
-static PyObject *
-err_restore(PyObject *self, PyObject *args) {
- PyObject *type = NULL, *value = NULL, *traceback = NULL;
- switch(PyTuple_Size(args)) {
- case 3:
- traceback = PyTuple_GetItem(args, 2);
- Py_INCREF(traceback);
- /* fall through */
- case 2:
- value = PyTuple_GetItem(args, 1);
- Py_INCREF(value);
- /* fall through */
- case 1:
- type = PyTuple_GetItem(args, 0);
- Py_INCREF(type);
- break;
- default:
- PyErr_SetString(PyExc_TypeError,
- "wrong number of arguments");
- return NULL;
- }
- PyErr_Restore(type, value, traceback);
- assert(PyErr_Occurred());
- return NULL;
-}
-
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
static PyMethodDef TestMethods[] = {
- {"raise_exception", raise_exception, METH_VARARGS},
- {"raise_memoryerror", raise_memoryerror, METH_NOARGS},
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
{"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS},
@@ -3574,15 +3361,9 @@ static PyMethodDef TestMethods[] = {
#ifdef HAVE_GETTIMEOFDAY
{"profile_int", profile_int, METH_NOARGS},
#endif
- {"traceback_print", traceback_print, METH_VARARGS},
- {"exception_print", exception_print, METH_VARARGS},
- {"set_exception", test_set_exception, METH_O},
- {"set_exc_info", test_set_exc_info, METH_VARARGS},
{"argparsing", argparsing, METH_VARARGS},
{"code_newempty", code_newempty, METH_VARARGS},
{"eval_code_ex", eval_eval_code_ex, METH_VARARGS},
- {"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
- METH_VARARGS | METH_KEYWORDS},
{"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer,
METH_NOARGS},
{"crash_no_current_thread", crash_no_current_thread, METH_NOARGS},
@@ -3633,7 +3414,6 @@ static PyMethodDef TestMethods[] = {
#ifdef Py_REF_DEBUG
{"negative_refcount", negative_refcount, METH_NOARGS},
#endif
- {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
{"sequence_getitem", sequence_getitem, METH_VARARGS},
{"sequence_setitem", sequence_setitem, METH_VARARGS},
{"sequence_delitem", sequence_delitem, METH_VARARGS},
@@ -3653,8 +3433,6 @@ static PyMethodDef TestMethods[] = {
{"test_refcount_funcs", test_refcount_funcs, METH_NOARGS},
{"test_py_is_macros", test_py_is_macros, METH_NOARGS},
{"test_py_is_funcs", test_py_is_funcs, METH_NOARGS},
- {"fatal_error", test_fatal_error, METH_VARARGS,
- PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
{"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")},
{"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
{"frame_getlocals", frame_getlocals, METH_O, NULL},
@@ -3680,8 +3458,6 @@ static PyMethodDef TestMethods[] = {
{"function_set_defaults", function_set_defaults, METH_VARARGS, NULL},
{"function_get_kw_defaults", function_get_kw_defaults, METH_O, NULL},
{"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL},
- {"err_set_raised", err_set_raised, METH_O, NULL},
- {"err_restore", err_restore, METH_VARARGS, NULL},
{NULL, NULL} /* sentinel */
};
@@ -3902,61 +3678,6 @@ static PyTypeObject awaitType = {
};
-static int recurse_infinitely_error_init(PyObject *, PyObject *, PyObject *);
-
-static PyTypeObject PyRecursingInfinitelyError_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "RecursingInfinitelyError", /* tp_name */
- sizeof(PyBaseExceptionObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- 0, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_as_async */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- PyDoc_STR("Instantiating this exception starts infinite recursion."), /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)recurse_infinitely_error_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-static int
-recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
- PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
-
- /* Instantiating this exception starts infinite recursion. */
- Py_INCREF(type);
- PyErr_SetObject(type, NULL);
- return -1;
-}
-
-
/* Test bpo-35983: create a subclass of "list" which checks that instances
* are not deallocated twice */
@@ -4283,14 +4004,6 @@ PyInit__testcapi(void)
Py_INCREF(&MethStatic_Type);
PyModule_AddObject(m, "MethStatic", (PyObject *)&MethStatic_Type);
- PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
- if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
- return NULL;
- }
- Py_INCREF(&PyRecursingInfinitelyError_Type);
- PyModule_AddObject(m, "RecursingInfinitelyError",
- (PyObject *)&PyRecursingInfinitelyError_Type);
-
PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX));
PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN));
PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX));
@@ -4368,6 +4081,9 @@ PyInit__testcapi(void)
if (_PyTestCapi_Init_Structmember(m) < 0) {
return NULL;
}
+ if (_PyTestCapi_Init_Exceptions(m) < 0) {
+ return NULL;
+ }
#ifndef LIMITED_API_AVAILABLE
PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False);