From 4912e142052c035491256e4d7ce1c8a33438c2d8 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Mon, 15 May 2023 18:01:31 +0900 Subject: [PATCH 1/6] gh-104469 Convert _testcapi/exceptions to use AC --- .../pycore_global_objects_fini_generated.h | 1 + Include/internal/pycore_global_strings.h | 1 + .../internal/pycore_runtime_init_generated.h | 1 + .../internal/pycore_unicodeobject_generated.h | 3 + Lib/test/test_capi/test_exceptions.py | 2 +- Lib/test/test_faulthandler.py | 2 +- Modules/_testcapi/clinic/exceptions.c.h | 461 ++++++++++++++++++ Modules/_testcapi/exceptions.c | 239 +++++---- 8 files changed, 611 insertions(+), 99 deletions(-) create mode 100644 Modules/_testcapi/clinic/exceptions.c.h diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 7e495817981f06..eae5abd981b7dc 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -899,6 +899,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(errors)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(event)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eventmask)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_type)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_value)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(excepthook)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 8ebfee85c87c23..800f9b46b9a217 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -387,6 +387,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(errors) STRUCT_FOR_ID(event) STRUCT_FOR_ID(eventmask) + STRUCT_FOR_ID(exc) STRUCT_FOR_ID(exc_type) STRUCT_FOR_ID(exc_value) STRUCT_FOR_ID(excepthook) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 7b9c73dd1edf3b..de1c977669089f 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -893,6 +893,7 @@ extern "C" { INIT_ID(errors), \ INIT_ID(event), \ INIT_ID(eventmask), \ + INIT_ID(exc), \ INIT_ID(exc_type), \ INIT_ID(exc_value), \ INIT_ID(excepthook), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 8e086edbdf8193..3b428d354f69f9 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -1014,6 +1014,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(eventmask); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(exc); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(exc_type); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); diff --git a/Lib/test/test_capi/test_exceptions.py b/Lib/test/test_capi/test_exceptions.py index b1c1a61e20685e..1081f40b6981af 100644 --- a/Lib/test/test_capi/test_exceptions.py +++ b/Lib/test/test_capi/test_exceptions.py @@ -66,7 +66,7 @@ def check_fatal_error(self, code, expected, not_expected=()): rc, out, err = assert_python_failure('-sSI', '-c', code) err = decode_stderr(err) - self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n', + self.assertIn('Fatal Python error: _testcapi_fatal_error_impl: MESSAGE\n', err) match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$', diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index 8d106daaf6520a..2e97de592712c0 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -270,7 +270,7 @@ def check_fatal_error_func(self, release_gil): """, 2, 'xyz', - func='test_fatal_error', + func='_testcapi_fatal_error_impl', py_fatal_error=True) def test_fatal_error(self): diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h new file mode 100644 index 00000000000000..c44c79f7ca38cc --- /dev/null +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -0,0 +1,461 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testcapi_err_set_raised__doc__, +"err_set_raised($module, exc, /)\n" +"--\n" +"\n" +"Test PyErr_SetRaisedException C API."); + +#define _TESTCAPI_ERR_SET_RAISED_METHODDEF \ + {"err_set_raised", (PyCFunction)_testcapi_err_set_raised, METH_O, _testcapi_err_set_raised__doc__}, + +PyDoc_STRVAR(_testcapi_exception_print__doc__, +"exception_print($module, exc, legacy=False, /)\n" +"--\n" +"\n" +"To test the format of exceptions as printed out."); + +#define _TESTCAPI_EXCEPTION_PRINT_METHODDEF \ + {"exception_print", _PyCFunction_CAST(_testcapi_exception_print), METH_FASTCALL, _testcapi_exception_print__doc__}, + +static PyObject * +_testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy); + +static PyObject * +_testcapi_exception_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + int legacy = 0; + + if (!_PyArg_CheckPositional("exception_print", nargs, 1, 2)) { + goto exit; + } + exc = args[0]; + if (nargs < 2) { + goto skip_optional; + } + legacy = PyObject_IsTrue(args[1]); + if (legacy < 0) { + goto exit; + } +skip_optional: + return_value = _testcapi_exception_print_impl(module, exc, legacy); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_make_exception_with_doc__doc__, +"make_exception_with_doc($module, /, name, doc=,\n" +" base=, dict=)\n" +"--\n" +"\n" +"Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py"); + +#define _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF \ + {"make_exception_with_doc", _PyCFunction_CAST(_testcapi_make_exception_with_doc), METH_FASTCALL|METH_KEYWORDS, _testcapi_make_exception_with_doc__doc__}, + +static PyObject * +_testcapi_make_exception_with_doc_impl(PyObject *module, const char *name, + const char *doc, PyObject *base, + PyObject *dict); + +static PyObject * +_testcapi_make_exception_with_doc(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(doc), &_Py_ID(base), &_Py_ID(dict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "doc", "base", "dict", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "make_exception_with_doc", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + const char *name; + const char *doc = NULL; + PyObject *base = NULL; + PyObject *dict = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("make_exception_with_doc", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("make_exception_with_doc", "argument 'doc'", "str", args[1]); + goto exit; + } + Py_ssize_t doc_length; + doc = PyUnicode_AsUTF8AndSize(args[1], &doc_length); + if (doc == NULL) { + goto exit; + } + if (strlen(doc) != (size_t)doc_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[2]) { + base = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + dict = args[3]; +skip_optional_pos: + return_value = _testcapi_make_exception_with_doc_impl(module, name, doc, base, dict); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_exc_set_object__doc__, +"exc_set_object($module, /, exc, obj)\n" +"--\n" +"\n" +"Test PyErr_SetObject C API."); + +#define _TESTCAPI_EXC_SET_OBJECT_METHODDEF \ + {"exc_set_object", _PyCFunction_CAST(_testcapi_exc_set_object), METH_FASTCALL|METH_KEYWORDS, _testcapi_exc_set_object__doc__}, + +static PyObject * +_testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj); + +static PyObject * +_testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(exc), &_Py_ID(obj), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"exc", "obj", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exc_set_object", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *exc; + PyObject *obj; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + exc = args[0]; + obj = args[1]; + return_value = _testcapi_exc_set_object_impl(module, exc, obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_exc_set_object_fetch__doc__, +"exc_set_object_fetch($module, /, exc, obj)\n" +"--\n" +"\n" +"Test PyErr_SetObject and PyErr_Fetch C APIs."); + +#define _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF \ + {"exc_set_object_fetch", _PyCFunction_CAST(_testcapi_exc_set_object_fetch), METH_FASTCALL|METH_KEYWORDS, _testcapi_exc_set_object_fetch__doc__}, + +static PyObject * +_testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, + PyObject *obj); + +static PyObject * +_testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(exc), &_Py_ID(obj), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"exc", "obj", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exc_set_object_fetch", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *exc; + PyObject *obj; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + exc = args[0]; + obj = args[1]; + return_value = _testcapi_exc_set_object_fetch_impl(module, exc, obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_raise_exception__doc__, +"raise_exception($module, exc, num_args, /)\n" +"--\n" +"\n" +"Test PyErr_SetObject for raising exception"); + +#define _TESTCAPI_RAISE_EXCEPTION_METHODDEF \ + {"raise_exception", _PyCFunction_CAST(_testcapi_raise_exception), METH_FASTCALL, _testcapi_raise_exception__doc__}, + +static PyObject * +_testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args); + +static PyObject * +_testcapi_raise_exception(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + int num_args; + + if (!_PyArg_CheckPositional("raise_exception", nargs, 2, 2)) { + goto exit; + } + exc = args[0]; + num_args = _PyLong_AsInt(args[1]); + if (num_args == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _testcapi_raise_exception_impl(module, exc, num_args); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_raise_memoryerror__doc__, +"raise_memoryerror($module, /)\n" +"--\n" +"\n" +"reliably raise a MemoryError"); + +#define _TESTCAPI_RAISE_MEMORYERROR_METHODDEF \ + {"raise_memoryerror", (PyCFunction)_testcapi_raise_memoryerror, METH_NOARGS, _testcapi_raise_memoryerror__doc__}, + +static PyObject * +_testcapi_raise_memoryerror_impl(PyObject *module); + +static PyObject * +_testcapi_raise_memoryerror(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _testcapi_raise_memoryerror_impl(module); +} + +PyDoc_STRVAR(_testcapi_fatal_error__doc__, +"fatal_error($module, message, release_gil=0, /)\n" +"--\n" +"\n" +"fatal_error(message, release_gil=False): call Py_FatalError(message)"); + +#define _TESTCAPI_FATAL_ERROR_METHODDEF \ + {"fatal_error", _PyCFunction_CAST(_testcapi_fatal_error), METH_FASTCALL, _testcapi_fatal_error__doc__}, + +static PyObject * +_testcapi_fatal_error_impl(PyObject *module, const char *message, + int release_gil); + +static PyObject * +_testcapi_fatal_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *message; + int release_gil = 0; + + if (!_PyArg_ParseStack(args, nargs, "y|i:fatal_error", + &message, &release_gil)) { + goto exit; + } + return_value = _testcapi_fatal_error_impl(module, message, release_gil); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_set_exc_info__doc__, +"set_exc_info($module, new_type, new_value, new_tb, /)\n" +"--\n" +"\n" +"Test PyErr_SetExcInfo C API."); + +#define _TESTCAPI_SET_EXC_INFO_METHODDEF \ + {"set_exc_info", _PyCFunction_CAST(_testcapi_set_exc_info), METH_FASTCALL, _testcapi_set_exc_info__doc__}, + +static PyObject * +_testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, + PyObject *new_value, PyObject *new_tb); + +static PyObject * +_testcapi_set_exc_info(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *new_type; + PyObject *new_value; + PyObject *new_tb; + + if (!_PyArg_CheckPositional("set_exc_info", nargs, 3, 3)) { + goto exit; + } + new_type = args[0]; + new_value = args[1]; + new_tb = args[2]; + return_value = _testcapi_set_exc_info_impl(module, new_type, new_value, new_tb); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_set_exception__doc__, +"set_exception($module, new_exc, /)\n" +"--\n" +"\n" +"Test PyErr_SetHandledException C API."); + +#define _TESTCAPI_SET_EXCEPTION_METHODDEF \ + {"set_exception", (PyCFunction)_testcapi_set_exception, METH_O, _testcapi_set_exception__doc__}, + +PyDoc_STRVAR(_testcapi_write_unraisable_exc__doc__, +"write_unraisable_exc($module, exc, err_msg, obj, /)\n" +"--\n" +"\n" +"Test _PyErr_WriteUnraisableMsg C API."); + +#define _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF \ + {"write_unraisable_exc", _PyCFunction_CAST(_testcapi_write_unraisable_exc), METH_FASTCALL, _testcapi_write_unraisable_exc__doc__}, + +static PyObject * +_testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, + PyObject *err_msg, PyObject *obj); + +static PyObject * +_testcapi_write_unraisable_exc(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + PyObject *err_msg; + PyObject *obj; + + if (!_PyArg_CheckPositional("write_unraisable_exc", nargs, 3, 3)) { + goto exit; + } + exc = args[0]; + err_msg = args[1]; + obj = args[2]; + return_value = _testcapi_write_unraisable_exc_impl(module, exc, err_msg, obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_traceback_print__doc__, +"traceback_print($module, traceback, file, /)\n" +"--\n" +"\n" +"To test the format of tracebacks as printed out."); + +#define _TESTCAPI_TRACEBACK_PRINT_METHODDEF \ + {"traceback_print", _PyCFunction_CAST(_testcapi_traceback_print), METH_FASTCALL, _testcapi_traceback_print__doc__}, + +static PyObject * +_testcapi_traceback_print_impl(PyObject *module, PyObject *traceback, + PyObject *file); + +static PyObject * +_testcapi_traceback_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *traceback; + PyObject *file; + + if (!_PyArg_CheckPositional("traceback_print", nargs, 2, 2)) { + goto exit; + } + traceback = args[0]; + file = args[1]; + return_value = _testcapi_traceback_print_impl(module, traceback, file); + +exit: + return return_value; +} +/*[clinic end generated code: output=f20b5ac4d0de3705 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index 6099f7d20eb56a..900db3fd9233c7 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -1,7 +1,21 @@ #include "parts.h" +#include "clinic/exceptions.c.h" + +/*[clinic input] +module _testcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ + +/*[clinic input] +_testcapi.err_set_raised + exc: object + / +Test PyErr_SetRaisedException C API. +[clinic start generated code]*/ static PyObject * -err_set_raised(PyObject *self, PyObject *exc) +_testcapi_err_set_raised(PyObject *module, PyObject *exc) +/*[clinic end generated code: output=0a0c7743961fcae5 input=65d91c54e94cb5dd]*/ { Py_INCREF(exc); PyErr_SetRaisedException(exc); @@ -35,16 +49,18 @@ err_restore(PyObject *self, PyObject *args) { return NULL; } -/* To test the format of exceptions as printed out. */ +/*[clinic input] +_testcapi.exception_print + exc: object + legacy: bool = False + / +To test the format of exceptions as printed out. +[clinic start generated code]*/ + static PyObject * -exception_print(PyObject *self, PyObject *args) +_testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy) +/*[clinic end generated code: output=3f04fe0c18412ae0 input=16da48a5d8581472]*/ { - PyObject *exc; - int legacy = 0; - - if (!PyArg_ParseTuple(args, "O|i:exception_print", &exc, &legacy)) { - return NULL; - } if (legacy) { PyObject *tb = NULL; if (PyExceptionInstance_Check(exc)) { @@ -59,55 +75,55 @@ exception_print(PyObject *self, PyObject *args) Py_RETURN_NONE; } -/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). - Run via Lib/test/test_exceptions.py */ +/*[clinic input] +_testcapi.make_exception_with_doc + name: str + doc: str = NULL + base: object = NULL + dict: object = NULL +Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py +[clinic start generated code]*/ + static PyObject * -make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs) +_testcapi_make_exception_with_doc_impl(PyObject *module, const char *name, + const char *doc, PyObject *base, + PyObject *dict) +/*[clinic end generated code: output=439f0d963c1ce2c4 input=4c78cd84f3d2ef1e]*/ { - 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); } +/*[clinic input] +_testcapi.exc_set_object + exc: object + obj: object +Test PyErr_SetObject C API. +[clinic start generated code]*/ + static PyObject * -exc_set_object(PyObject *self, PyObject *args) +_testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj) +/*[clinic end generated code: output=34c8c7c83e5c8463 input=a5b44b5f4839a8f0]*/ { - PyObject *exc; - PyObject *obj; - - if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) { - return NULL; - } - PyErr_SetObject(exc, obj); return NULL; } +/*[clinic input] +_testcapi.exc_set_object_fetch + exc: object + obj: object +Test PyErr_SetObject and PyErr_Fetch C APIs. +[clinic start generated code]*/ + static PyObject * -exc_set_object_fetch(PyObject *self, PyObject *args) +_testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, + PyObject *obj) +/*[clinic end generated code: output=7a5ff5f6d3cf687f input=6940a2113786ed2b]*/ { - PyObject *exc; - PyObject *obj; PyObject *type; PyObject *value; PyObject *tb; - if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) { - return NULL; - } - PyErr_SetObject(exc, obj); PyErr_Fetch(&type, &value, &tb); Py_XDECREF(type); @@ -115,16 +131,18 @@ exc_set_object_fetch(PyObject *self, PyObject *args) return value; } +/*[clinic input] +_testcapi.raise_exception + exc: object + num_args: int + / +Test PyErr_SetObject for raising exception +[clinic start generated code]*/ + static PyObject * -raise_exception(PyObject *self, PyObject *args) +_testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args) +/*[clinic end generated code: output=eb0a9c5d69e0542d input=912b1bb1cd2346c3]*/ { - 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; @@ -142,21 +160,32 @@ raise_exception(PyObject *self, PyObject *args) return NULL; } -/* reliably raise a MemoryError */ +/*[clinic input] +_testcapi.raise_memoryerror + +reliably raise a MemoryError +[clinic start generated code]*/ + static PyObject * -raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored)) +_testcapi_raise_memoryerror_impl(PyObject *module) +/*[clinic end generated code: output=dd057803fb0131e6 input=00e9d6f183604386]*/ { return PyErr_NoMemory(); } +/*[clinic input] +_testcapi.fatal_error + message: str(accept={robuffer}) + release_gil: int = 0 + / +fatal_error(message, release_gil=False): call Py_FatalError(message) +[clinic start generated code]*/ + static PyObject * -test_fatal_error(PyObject *self, PyObject *args) +_testcapi_fatal_error_impl(PyObject *module, const char *message, + int release_gil) +/*[clinic end generated code: output=9c3237116e6a03e8 input=50a85c024226f44f]*/ { - 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); @@ -169,17 +198,21 @@ test_fatal_error(PyObject *self, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_testcapi.set_exc_info + new_type: object + new_value: object + new_tb: object + / +Test PyErr_SetExcInfo C API. +[clinic start generated code]*/ + static PyObject * -test_set_exc_info(PyObject *self, PyObject *args) +_testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, + PyObject *new_value, PyObject *new_tb) +/*[clinic end generated code: output=b55fa35dec31300e input=ce612545fb3f7200]*/ { - 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); @@ -197,23 +230,37 @@ test_set_exc_info(PyObject *self, PyObject *args) return orig_exc; } +/*[clinic input] +_testcapi.set_exception + new_exc: object + / +Test PyErr_SetHandledException C API. +[clinic start generated code]*/ + static PyObject * -test_set_exception(PyObject *self, PyObject *new_exc) +_testcapi_set_exception(PyObject *module, PyObject *new_exc) +/*[clinic end generated code: output=8b969b35d029e96d input=356cd44e13128aa0]*/ { PyObject *exc = PyErr_GetHandledException(); assert(PyExceptionInstance_Check(exc) || exc == NULL); - PyErr_SetHandledException(new_exc); return exc; } +/*[clinic input] +_testcapi.write_unraisable_exc + exc: object + err_msg: object + obj: object + / +Test _PyErr_WriteUnraisableMsg C API. +[clinic start generated code]*/ + static PyObject * -test_write_unraisable_exc(PyObject *self, PyObject *args) +_testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, + PyObject *err_msg, PyObject *obj) +/*[clinic end generated code: output=39827c5e0a8c2092 input=35e060a34a8d388a]*/ { - 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) { @@ -231,19 +278,19 @@ test_write_unraisable_exc(PyObject *self, PyObject *args) Py_RETURN_NONE; } -/* To test the format of tracebacks as printed out. */ +/*[clinic input] +_testcapi.traceback_print + traceback: object + file: object + / +To test the format of tracebacks as printed out. +[clinic start generated code]*/ + static PyObject * -traceback_print(PyObject *self, PyObject *args) +_testcapi_traceback_print_impl(PyObject *module, PyObject *traceback, + PyObject *file) +/*[clinic end generated code: output=17074ecf9d95cf30 input=9423f2857b008ca8]*/ { - PyObject *file; - PyObject *traceback; - - if (!PyArg_ParseTuple(args, "OO:traceback_print", - &traceback, &file)) - { - return NULL; - } - if (PyTraceBack_Print(traceback, file) < 0) { return NULL; } @@ -278,20 +325,18 @@ static PyTypeObject PyRecursingInfinitelyError_Type = { 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}, - {"exc_set_object", exc_set_object, METH_VARARGS}, - {"exc_set_object_fetch", exc_set_object_fetch, METH_VARARGS}, - {"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}, + _TESTCAPI_ERR_SET_RAISED_METHODDEF + _TESTCAPI_EXCEPTION_PRINT_METHODDEF + _TESTCAPI_FATAL_ERROR_METHODDEF + _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF + _TESTCAPI_EXC_SET_OBJECT_METHODDEF + _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF + _TESTCAPI_RAISE_EXCEPTION_METHODDEF + _TESTCAPI_RAISE_MEMORYERROR_METHODDEF + _TESTCAPI_SET_EXC_INFO_METHODDEF + _TESTCAPI_SET_EXCEPTION_METHODDEF + _TESTCAPI_TRACEBACK_PRINT_METHODDEF + _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF {NULL}, }; From 1b085dce1c7a6a300ed65d2db02dd4189be9ef9f Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Mon, 15 May 2023 18:50:21 +0900 Subject: [PATCH 2/6] Fix signature --- Modules/_testcapi/clinic/exceptions.c.h | 6 +++--- Modules/_testcapi/exceptions.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h index c44c79f7ca38cc..ce439c27b67fcb 100644 --- a/Modules/_testcapi/clinic/exceptions.c.h +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -324,7 +324,7 @@ _testcapi_raise_memoryerror(PyObject *module, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(_testcapi_fatal_error__doc__, -"fatal_error($module, message, release_gil=0, /)\n" +"fatal_error($module, message, release_gil=False, /)\n" "--\n" "\n" "fatal_error(message, release_gil=False): call Py_FatalError(message)"); @@ -343,7 +343,7 @@ _testcapi_fatal_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const char *message; int release_gil = 0; - if (!_PyArg_ParseStack(args, nargs, "y|i:fatal_error", + if (!_PyArg_ParseStack(args, nargs, "y|p:fatal_error", &message, &release_gil)) { goto exit; } @@ -458,4 +458,4 @@ _testcapi_traceback_print(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=f20b5ac4d0de3705 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=61dfe5aadcb50f13 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index 900db3fd9233c7..4d08898a665fdb 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -176,7 +176,7 @@ _testcapi_raise_memoryerror_impl(PyObject *module) /*[clinic input] _testcapi.fatal_error message: str(accept={robuffer}) - release_gil: int = 0 + release_gil: bool = False / fatal_error(message, release_gil=False): call Py_FatalError(message) [clinic start generated code]*/ @@ -184,7 +184,7 @@ fatal_error(message, release_gil=False): call Py_FatalError(message) static PyObject * _testcapi_fatal_error_impl(PyObject *module, const char *message, int release_gil) -/*[clinic end generated code: output=9c3237116e6a03e8 input=50a85c024226f44f]*/ +/*[clinic end generated code: output=9c3237116e6a03e8 input=56f76191e4b152d7]*/ { if (release_gil) { Py_BEGIN_ALLOW_THREADS From 03de258613f2e365762143bc444271390f04be11 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 17 May 2023 21:16:32 +0900 Subject: [PATCH 3/6] Follow the guideline --- .../pycore_global_objects_fini_generated.h | 1 - Include/internal/pycore_global_strings.h | 1 - .../internal/pycore_runtime_init_generated.h | 1 - .../internal/pycore_unicodeobject_generated.h | 3 -- Modules/_testcapi/clinic/exceptions.c.h | 43 ++++++++----------- Modules/_testcapi/exceptions.c | 42 ++++++++---------- 6 files changed, 37 insertions(+), 54 deletions(-) diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index eae5abd981b7dc..7e495817981f06 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -899,7 +899,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(errors)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(event)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eventmask)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_type)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_value)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(excepthook)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 800f9b46b9a217..8ebfee85c87c23 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -387,7 +387,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(errors) STRUCT_FOR_ID(event) STRUCT_FOR_ID(eventmask) - STRUCT_FOR_ID(exc) STRUCT_FOR_ID(exc_type) STRUCT_FOR_ID(exc_value) STRUCT_FOR_ID(excepthook) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index de1c977669089f..7b9c73dd1edf3b 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -893,7 +893,6 @@ extern "C" { INIT_ID(errors), \ INIT_ID(event), \ INIT_ID(eventmask), \ - INIT_ID(exc), \ INIT_ID(exc_type), \ INIT_ID(exc_value), \ INIT_ID(excepthook), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 3b428d354f69f9..8e086edbdf8193 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -1014,9 +1014,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(eventmask); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(exc); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(exc_type); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h index ce439c27b67fcb..963fa21e85b063 100644 --- a/Modules/_testcapi/clinic/exceptions.c.h +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -9,16 +9,15 @@ preserve PyDoc_STRVAR(_testcapi_err_set_raised__doc__, -"err_set_raised($module, exc, /)\n" +"err_set_raised($module, exception, /)\n" "--\n" -"\n" -"Test PyErr_SetRaisedException C API."); +"\n"); #define _TESTCAPI_ERR_SET_RAISED_METHODDEF \ {"err_set_raised", (PyCFunction)_testcapi_err_set_raised, METH_O, _testcapi_err_set_raised__doc__}, PyDoc_STRVAR(_testcapi_exception_print__doc__, -"exception_print($module, exc, legacy=False, /)\n" +"exception_print($module, exception, legacy=False, /)\n" "--\n" "\n" "To test the format of exceptions as printed out."); @@ -158,10 +157,9 @@ _testcapi_make_exception_with_doc(PyObject *module, PyObject *const *args, Py_ss } PyDoc_STRVAR(_testcapi_exc_set_object__doc__, -"exc_set_object($module, /, exc, obj)\n" +"exc_set_object($module, /, exception, obj)\n" "--\n" -"\n" -"Test PyErr_SetObject C API."); +"\n"); #define _TESTCAPI_EXC_SET_OBJECT_METHODDEF \ {"exc_set_object", _PyCFunction_CAST(_testcapi_exc_set_object), METH_FASTCALL|METH_KEYWORDS, _testcapi_exc_set_object__doc__}, @@ -182,7 +180,7 @@ _testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nar PyObject *ob_item[NUM_KEYWORDS]; } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(exc), &_Py_ID(obj), }, + .ob_item = { &_Py_ID(exception), &_Py_ID(obj), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -191,7 +189,7 @@ _testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nar # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"exc", "obj", NULL}; + static const char * const _keywords[] = {"exception", "obj", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "exc_set_object", @@ -215,10 +213,9 @@ _testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nar } PyDoc_STRVAR(_testcapi_exc_set_object_fetch__doc__, -"exc_set_object_fetch($module, /, exc, obj)\n" +"exc_set_object_fetch($module, /, exception, obj)\n" "--\n" -"\n" -"Test PyErr_SetObject and PyErr_Fetch C APIs."); +"\n"); #define _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF \ {"exc_set_object_fetch", _PyCFunction_CAST(_testcapi_exc_set_object_fetch), METH_FASTCALL|METH_KEYWORDS, _testcapi_exc_set_object_fetch__doc__}, @@ -240,7 +237,7 @@ _testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize PyObject *ob_item[NUM_KEYWORDS]; } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(exc), &_Py_ID(obj), }, + .ob_item = { &_Py_ID(exception), &_Py_ID(obj), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -249,7 +246,7 @@ _testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"exc", "obj", NULL}; + static const char * const _keywords[] = {"exception", "obj", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "exc_set_object_fetch", @@ -273,10 +270,9 @@ _testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize } PyDoc_STRVAR(_testcapi_raise_exception__doc__, -"raise_exception($module, exc, num_args, /)\n" +"raise_exception($module, exception, num_args, /)\n" "--\n" -"\n" -"Test PyErr_SetObject for raising exception"); +"\n"); #define _TESTCAPI_RAISE_EXCEPTION_METHODDEF \ {"raise_exception", _PyCFunction_CAST(_testcapi_raise_exception), METH_FASTCALL, _testcapi_raise_exception__doc__}, @@ -356,8 +352,7 @@ _testcapi_fatal_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyDoc_STRVAR(_testcapi_set_exc_info__doc__, "set_exc_info($module, new_type, new_value, new_tb, /)\n" "--\n" -"\n" -"Test PyErr_SetExcInfo C API."); +"\n"); #define _TESTCAPI_SET_EXC_INFO_METHODDEF \ {"set_exc_info", _PyCFunction_CAST(_testcapi_set_exc_info), METH_FASTCALL, _testcapi_set_exc_info__doc__}, @@ -389,17 +384,15 @@ _testcapi_set_exc_info(PyObject *module, PyObject *const *args, Py_ssize_t nargs PyDoc_STRVAR(_testcapi_set_exception__doc__, "set_exception($module, new_exc, /)\n" "--\n" -"\n" -"Test PyErr_SetHandledException C API."); +"\n"); #define _TESTCAPI_SET_EXCEPTION_METHODDEF \ {"set_exception", (PyCFunction)_testcapi_set_exception, METH_O, _testcapi_set_exception__doc__}, PyDoc_STRVAR(_testcapi_write_unraisable_exc__doc__, -"write_unraisable_exc($module, exc, err_msg, obj, /)\n" +"write_unraisable_exc($module, exception, err_msg, obj, /)\n" "--\n" -"\n" -"Test _PyErr_WriteUnraisableMsg C API."); +"\n"); #define _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF \ {"write_unraisable_exc", _PyCFunction_CAST(_testcapi_write_unraisable_exc), METH_FASTCALL, _testcapi_write_unraisable_exc__doc__}, @@ -458,4 +451,4 @@ _testcapi_traceback_print(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=61dfe5aadcb50f13 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9076f55ae0673fee input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index 4d08898a665fdb..621bbc211db4cb 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -8,14 +8,13 @@ module _testcapi /*[clinic input] _testcapi.err_set_raised - exc: object + exception as exc: object / -Test PyErr_SetRaisedException C API. [clinic start generated code]*/ static PyObject * _testcapi_err_set_raised(PyObject *module, PyObject *exc) -/*[clinic end generated code: output=0a0c7743961fcae5 input=65d91c54e94cb5dd]*/ +/*[clinic end generated code: output=0a0c7743961fcae5 input=c5f7331864a94df9]*/ { Py_INCREF(exc); PyErr_SetRaisedException(exc); @@ -51,15 +50,16 @@ err_restore(PyObject *self, PyObject *args) { /*[clinic input] _testcapi.exception_print - exc: object + exception as exc: object legacy: bool = False / + To test the format of exceptions as printed out. [clinic start generated code]*/ static PyObject * _testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy) -/*[clinic end generated code: output=3f04fe0c18412ae0 input=16da48a5d8581472]*/ +/*[clinic end generated code: output=3f04fe0c18412ae0 input=c76f42cb94136dbf]*/ { if (legacy) { PyObject *tb = NULL; @@ -81,6 +81,7 @@ _testcapi.make_exception_with_doc doc: str = NULL base: object = NULL dict: object = NULL + Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py [clinic start generated code]*/ @@ -88,21 +89,20 @@ static PyObject * _testcapi_make_exception_with_doc_impl(PyObject *module, const char *name, const char *doc, PyObject *base, PyObject *dict) -/*[clinic end generated code: output=439f0d963c1ce2c4 input=4c78cd84f3d2ef1e]*/ +/*[clinic end generated code: output=439f0d963c1ce2c4 input=23a73013f8a8795a]*/ { return PyErr_NewExceptionWithDoc(name, doc, base, dict); } /*[clinic input] _testcapi.exc_set_object - exc: object + exception as exc: object obj: object -Test PyErr_SetObject C API. [clinic start generated code]*/ static PyObject * _testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj) -/*[clinic end generated code: output=34c8c7c83e5c8463 input=a5b44b5f4839a8f0]*/ +/*[clinic end generated code: output=34c8c7c83e5c8463 input=d2ccbcb97e67d3c2]*/ { PyErr_SetObject(exc, obj); return NULL; @@ -110,15 +110,14 @@ _testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj) /*[clinic input] _testcapi.exc_set_object_fetch - exc: object + exception as exc: object obj: object -Test PyErr_SetObject and PyErr_Fetch C APIs. [clinic start generated code]*/ static PyObject * _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, PyObject *obj) -/*[clinic end generated code: output=7a5ff5f6d3cf687f input=6940a2113786ed2b]*/ +/*[clinic end generated code: output=7a5ff5f6d3cf687f input=0f2675f24fe95093]*/ { PyObject *type; PyObject *value; @@ -133,15 +132,14 @@ _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, /*[clinic input] _testcapi.raise_exception - exc: object + exception as exc: object num_args: int / -Test PyErr_SetObject for raising exception [clinic start generated code]*/ static PyObject * _testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args) -/*[clinic end generated code: output=eb0a9c5d69e0542d input=912b1bb1cd2346c3]*/ +/*[clinic end generated code: output=eb0a9c5d69e0542d input=83d6262c3829d088]*/ { PyObject *exc_args = PyTuple_New(num_args); if (exc_args == NULL) { @@ -178,13 +176,14 @@ _testcapi.fatal_error message: str(accept={robuffer}) release_gil: bool = False / + fatal_error(message, release_gil=False): call Py_FatalError(message) [clinic start generated code]*/ static PyObject * _testcapi_fatal_error_impl(PyObject *module, const char *message, int release_gil) -/*[clinic end generated code: output=9c3237116e6a03e8 input=56f76191e4b152d7]*/ +/*[clinic end generated code: output=9c3237116e6a03e8 input=3d1709d2936fe086]*/ { if (release_gil) { Py_BEGIN_ALLOW_THREADS @@ -204,13 +203,12 @@ _testcapi.set_exc_info new_value: object new_tb: object / -Test PyErr_SetExcInfo C API. [clinic start generated code]*/ static PyObject * _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, PyObject *new_value, PyObject *new_tb) -/*[clinic end generated code: output=b55fa35dec31300e input=ce612545fb3f7200]*/ +/*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/ { PyObject *type, *value, *tb; PyErr_GetExcInfo(&type, &value, &tb); @@ -234,12 +232,11 @@ _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, _testcapi.set_exception new_exc: object / -Test PyErr_SetHandledException C API. [clinic start generated code]*/ static PyObject * _testcapi_set_exception(PyObject *module, PyObject *new_exc) -/*[clinic end generated code: output=8b969b35d029e96d input=356cd44e13128aa0]*/ +/*[clinic end generated code: output=8b969b35d029e96d input=c89d4ca966c69738]*/ { PyObject *exc = PyErr_GetHandledException(); assert(PyExceptionInstance_Check(exc) || exc == NULL); @@ -249,17 +246,16 @@ _testcapi_set_exception(PyObject *module, PyObject *new_exc) /*[clinic input] _testcapi.write_unraisable_exc - exc: object + exception as exc: object err_msg: object obj: object / -Test _PyErr_WriteUnraisableMsg C API. [clinic start generated code]*/ static PyObject * _testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, PyObject *err_msg, PyObject *obj) -/*[clinic end generated code: output=39827c5e0a8c2092 input=35e060a34a8d388a]*/ +/*[clinic end generated code: output=39827c5e0a8c2092 input=582498da5b2ee6cf]*/ { const char *err_msg_utf8; From b81f4722e7236a2353ba87a7eebde193c03d9560 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 17 May 2023 21:21:50 +0900 Subject: [PATCH 4/6] Unified params --- Modules/_testcapi/exceptions.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index 621bbc211db4cb..219acc731bf389 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -109,15 +109,13 @@ _testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj) } /*[clinic input] -_testcapi.exc_set_object_fetch - exception as exc: object - obj: object +_testcapi.exc_set_object_fetch = _testcapi.exc_set_object [clinic start generated code]*/ static PyObject * _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, PyObject *obj) -/*[clinic end generated code: output=7a5ff5f6d3cf687f input=0f2675f24fe95093]*/ +/*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/ { PyObject *type; PyObject *value; From 19918cf5dff8d8ecf8ae057e3e71b1b090de3de4 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Thu, 18 May 2023 10:00:43 +0900 Subject: [PATCH 5/6] Address code review --- Modules/_testcapi/clinic/exceptions.c.h | 72 ++++--------------------- Modules/_testcapi/exceptions.c | 3 +- 2 files changed, 11 insertions(+), 64 deletions(-) diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h index 963fa21e85b063..14f30ef9950e8b 100644 --- a/Modules/_testcapi/clinic/exceptions.c.h +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -157,51 +157,24 @@ _testcapi_make_exception_with_doc(PyObject *module, PyObject *const *args, Py_ss } PyDoc_STRVAR(_testcapi_exc_set_object__doc__, -"exc_set_object($module, /, exception, obj)\n" +"exc_set_object($module, exception, obj, /)\n" "--\n" "\n"); #define _TESTCAPI_EXC_SET_OBJECT_METHODDEF \ - {"exc_set_object", _PyCFunction_CAST(_testcapi_exc_set_object), METH_FASTCALL|METH_KEYWORDS, _testcapi_exc_set_object__doc__}, + {"exc_set_object", _PyCFunction_CAST(_testcapi_exc_set_object), METH_FASTCALL, _testcapi_exc_set_object__doc__}, static PyObject * _testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj); static PyObject * -_testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 2 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(exception), &_Py_ID(obj), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"exception", "obj", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "exc_set_object", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; PyObject *exc; PyObject *obj; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { + if (!_PyArg_CheckPositional("exc_set_object", nargs, 2, 2)) { goto exit; } exc = args[0]; @@ -213,52 +186,25 @@ _testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nar } PyDoc_STRVAR(_testcapi_exc_set_object_fetch__doc__, -"exc_set_object_fetch($module, /, exception, obj)\n" +"exc_set_object_fetch($module, exception, obj, /)\n" "--\n" "\n"); #define _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF \ - {"exc_set_object_fetch", _PyCFunction_CAST(_testcapi_exc_set_object_fetch), METH_FASTCALL|METH_KEYWORDS, _testcapi_exc_set_object_fetch__doc__}, + {"exc_set_object_fetch", _PyCFunction_CAST(_testcapi_exc_set_object_fetch), METH_FASTCALL, _testcapi_exc_set_object_fetch__doc__}, static PyObject * _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, PyObject *obj); static PyObject * -_testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 2 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(exception), &_Py_ID(obj), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"exception", "obj", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "exc_set_object_fetch", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; PyObject *exc; PyObject *obj; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { + if (!_PyArg_CheckPositional("exc_set_object_fetch", nargs, 2, 2)) { goto exit; } exc = args[0]; @@ -451,4 +397,4 @@ _testcapi_traceback_print(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=9076f55ae0673fee input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ee4a6d2d08c23e0a input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index 219acc731bf389..0b4f1db7db4165 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -98,11 +98,12 @@ _testcapi_make_exception_with_doc_impl(PyObject *module, const char *name, _testcapi.exc_set_object exception as exc: object obj: object + / [clinic start generated code]*/ static PyObject * _testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj) -/*[clinic end generated code: output=34c8c7c83e5c8463 input=d2ccbcb97e67d3c2]*/ +/*[clinic end generated code: output=34c8c7c83e5c8463 input=fc530aafb1b0a360]*/ { PyErr_SetObject(exc, obj); return NULL; From 74af1a5dfa4336144b5ac190f163104ac2fd3258 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 19 May 2023 20:55:50 +0900 Subject: [PATCH 6/6] Address code review --- Modules/_testcapi/clinic/exceptions.c.h | 8 +++----- Modules/_testcapi/exceptions.c | 8 ++------ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h index 14f30ef9950e8b..2cc4ef3dc0d497 100644 --- a/Modules/_testcapi/clinic/exceptions.c.h +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -250,8 +250,7 @@ _testcapi_raise_exception(PyObject *module, PyObject *const *args, Py_ssize_t na PyDoc_STRVAR(_testcapi_raise_memoryerror__doc__, "raise_memoryerror($module, /)\n" "--\n" -"\n" -"reliably raise a MemoryError"); +"\n"); #define _TESTCAPI_RAISE_MEMORYERROR_METHODDEF \ {"raise_memoryerror", (PyCFunction)_testcapi_raise_memoryerror, METH_NOARGS, _testcapi_raise_memoryerror__doc__}, @@ -268,8 +267,7 @@ _testcapi_raise_memoryerror(PyObject *module, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(_testcapi_fatal_error__doc__, "fatal_error($module, message, release_gil=False, /)\n" "--\n" -"\n" -"fatal_error(message, release_gil=False): call Py_FatalError(message)"); +"\n"); #define _TESTCAPI_FATAL_ERROR_METHODDEF \ {"fatal_error", _PyCFunction_CAST(_testcapi_fatal_error), METH_FASTCALL, _testcapi_fatal_error__doc__}, @@ -397,4 +395,4 @@ _testcapi_traceback_print(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=ee4a6d2d08c23e0a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ec1b2e62adea9846 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index 0b4f1db7db4165..0a9902c135a7e5 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -159,13 +159,11 @@ _testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args) /*[clinic input] _testcapi.raise_memoryerror - -reliably raise a MemoryError [clinic start generated code]*/ static PyObject * _testcapi_raise_memoryerror_impl(PyObject *module) -/*[clinic end generated code: output=dd057803fb0131e6 input=00e9d6f183604386]*/ +/*[clinic end generated code: output=dd057803fb0131e6 input=6ca521bd07fb73cb]*/ { return PyErr_NoMemory(); } @@ -175,14 +173,12 @@ _testcapi.fatal_error message: str(accept={robuffer}) release_gil: bool = False / - -fatal_error(message, release_gil=False): call Py_FatalError(message) [clinic start generated code]*/ static PyObject * _testcapi_fatal_error_impl(PyObject *module, const char *message, int release_gil) -/*[clinic end generated code: output=9c3237116e6a03e8 input=3d1709d2936fe086]*/ +/*[clinic end generated code: output=9c3237116e6a03e8 input=1be357a2ccb04c8c]*/ { if (release_gil) { Py_BEGIN_ALLOW_THREADS