LCOV - code coverage report
Current view: | top level - Modules/_testcapi - exceptions.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 6 | 126 | 4.8 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 1 | 15 | 6.7 %
|  |  | Branches: | 3 | 56 | 5.4 %

               Branch data     Line data    Source code
           1                 :            : #include "parts.h"
           2                 :            :
           3                 :            : static PyObject *
           4                 :          0 : err_set_raised(PyObject *self, PyObject *exc)
           5                 :            : {
           6                 :          0 :     Py_INCREF(exc);
           7                 :          0 :     PyErr_SetRaisedException(exc);
           8         [ #  # ]:          0 :     assert(PyErr_Occurred());
           9                 :          0 :     return NULL;
          10                 :            : }
          11                 :            :
          12                 :            : static PyObject *
          13                 :          0 : err_restore(PyObject *self, PyObject *args) {
          14                 :          0 :     PyObject *type = NULL, *value = NULL, *traceback = NULL;
          15   [ #  #  #  # ]:          0 :     switch(PyTuple_Size(args)) {
          16                 :          0 :         case 3:
          17                 :          0 :             traceback = PyTuple_GetItem(args, 2);
          18                 :          0 :             Py_INCREF(traceback);
          19                 :            :             /* fall through */
          20                 :          0 :         case 2:
          21                 :          0 :             value = PyTuple_GetItem(args, 1);
          22                 :          0 :             Py_INCREF(value);
          23                 :            :             /* fall through */
          24                 :          0 :         case 1:
          25                 :          0 :             type = PyTuple_GetItem(args, 0);
          26                 :          0 :             Py_INCREF(type);
          27                 :          0 :             break;
          28                 :          0 :         default:
          29                 :          0 :             PyErr_SetString(PyExc_TypeError,
          30                 :            :                         "wrong number of arguments");
          31                 :          0 :             return NULL;
          32                 :            :     }
          33                 :          0 :     PyErr_Restore(type, value, traceback);
          34         [ #  # ]:          0 :     assert(PyErr_Occurred());
          35                 :          0 :     return NULL;
          36                 :            : }
          37                 :            :
          38                 :            : /* To test the format of exceptions as printed out. */
          39                 :            : static PyObject *
          40                 :          0 : exception_print(PyObject *self, PyObject *args)
          41                 :            : {
          42                 :            :     PyObject *exc;
          43                 :            :
          44         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "O:exception_print", &exc)) {
          45                 :          0 :         return NULL;
          46                 :            :     }
          47                 :            :
          48                 :          0 :     PyErr_DisplayException(exc);
          49                 :          0 :     Py_RETURN_NONE;
          50                 :            : }
          51                 :            :
          52                 :            : /* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException).
          53                 :            :    Run via Lib/test/test_exceptions.py */
          54                 :            : static PyObject *
          55                 :          0 : make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs)
          56                 :            : {
          57                 :            :     const char *name;
          58                 :          0 :     const char *doc = NULL;
          59                 :          0 :     PyObject *base = NULL;
          60                 :          0 :     PyObject *dict = NULL;
          61                 :            :
          62                 :            :     static char *kwlist[] = {"name", "doc", "base", "dict", NULL};
          63                 :            :
          64         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
          65                 :            :                                      "s|sOO:make_exception_with_doc", kwlist,
          66                 :            :                                      &name, &doc, &base, &dict))
          67                 :            :     {
          68                 :          0 :         return NULL;
          69                 :            :     }
          70                 :            :
          71                 :          0 :     return PyErr_NewExceptionWithDoc(name, doc, base, dict);
          72                 :            : }
          73                 :            :
          74                 :            : static PyObject *
          75                 :          0 : exc_set_object(PyObject *self, PyObject *args)
          76                 :            : {
          77                 :            :     PyObject *exc;
          78                 :            :     PyObject *obj;
          79                 :            :
          80         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) {
          81                 :          0 :         return NULL;
          82                 :            :     }
          83                 :            :
          84                 :          0 :     PyErr_SetObject(exc, obj);
          85                 :          0 :     return NULL;
          86                 :            : }
          87                 :            :
          88                 :            : static PyObject *
          89                 :          0 : exc_set_object_fetch(PyObject *self, PyObject *args)
          90                 :            : {
          91                 :            :     PyObject *exc;
          92                 :            :     PyObject *obj;
          93                 :            :     PyObject *type;
          94                 :            :     PyObject *value;
          95                 :            :     PyObject *tb;
          96                 :            :
          97         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "OO:exc_set_object", &exc, &obj)) {
          98                 :          0 :         return NULL;
          99                 :            :     }
         100                 :            :
         101                 :          0 :     PyErr_SetObject(exc, obj);
         102                 :          0 :     PyErr_Fetch(&type, &value, &tb);
         103                 :          0 :     Py_XDECREF(type);
         104                 :          0 :     Py_XDECREF(tb);
         105                 :          0 :     return value;
         106                 :            : }
         107                 :            :
         108                 :            : static PyObject *
         109                 :          0 : raise_exception(PyObject *self, PyObject *args)
         110                 :            : {
         111                 :            :     PyObject *exc;
         112                 :            :     int num_args;
         113                 :            :
         114         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "Oi:raise_exception", &exc, &num_args)) {
         115                 :          0 :         return NULL;
         116                 :            :     }
         117                 :            :
         118                 :          0 :     PyObject *exc_args = PyTuple_New(num_args);
         119         [ #  # ]:          0 :     if (exc_args == NULL) {
         120                 :          0 :         return NULL;
         121                 :            :     }
         122         [ #  # ]:          0 :     for (int i = 0; i < num_args; ++i) {
         123                 :          0 :         PyObject *v = PyLong_FromLong(i);
         124         [ #  # ]:          0 :         if (v == NULL) {
         125                 :          0 :             Py_DECREF(exc_args);
         126                 :          0 :             return NULL;
         127                 :            :         }
         128                 :          0 :         PyTuple_SET_ITEM(exc_args, i, v);
         129                 :            :     }
         130                 :          0 :     PyErr_SetObject(exc, exc_args);
         131                 :          0 :     Py_DECREF(exc_args);
         132                 :          0 :     return NULL;
         133                 :            : }
         134                 :            :
         135                 :            : /* reliably raise a MemoryError */
         136                 :            : static PyObject *
         137                 :          0 : raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored))
         138                 :            : {
         139                 :          0 :     return PyErr_NoMemory();
         140                 :            : }
         141                 :            :
         142                 :            : static PyObject *
         143                 :          0 : test_fatal_error(PyObject *self, PyObject *args)
         144                 :            : {
         145                 :            :     char *message;
         146                 :          0 :     int release_gil = 0;
         147         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) {
         148                 :          0 :         return NULL;
         149                 :            :     }
         150         [ #  # ]:          0 :     if (release_gil) {
         151                 :          0 :         Py_BEGIN_ALLOW_THREADS
         152                 :          0 :         Py_FatalError(message);
         153                 :            :         Py_END_ALLOW_THREADS
         154                 :            :     }
         155                 :            :     else {
         156                 :          0 :         Py_FatalError(message);
         157                 :            :     }
         158                 :            :     // Py_FatalError() does not return, but exits the process.
         159                 :            :     Py_RETURN_NONE;
         160                 :            : }
         161                 :            :
         162                 :            : static PyObject *
         163                 :          0 : test_set_exc_info(PyObject *self, PyObject *args)
         164                 :            : {
         165                 :            :     PyObject *new_type, *new_value, *new_tb;
         166                 :            :     PyObject *type, *value, *tb;
         167         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info",
         168                 :            :                           &new_type, &new_value, &new_tb))
         169                 :            :     {
         170                 :          0 :         return NULL;
         171                 :            :     }
         172                 :            :
         173                 :          0 :     PyErr_GetExcInfo(&type, &value, &tb);
         174                 :            :
         175                 :          0 :     Py_INCREF(new_type);
         176                 :          0 :     Py_INCREF(new_value);
         177                 :          0 :     Py_INCREF(new_tb);
         178                 :          0 :     PyErr_SetExcInfo(new_type, new_value, new_tb);
         179                 :            :
         180                 :          0 :     PyObject *orig_exc = PyTuple_Pack(3,
         181         [ #  # ]:          0 :             type  ? type  : Py_None,
         182         [ #  # ]:          0 :             value ? value : Py_None,
         183         [ #  # ]:          0 :             tb    ? tb    : Py_None);
         184                 :          0 :     Py_XDECREF(type);
         185                 :          0 :     Py_XDECREF(value);
         186                 :          0 :     Py_XDECREF(tb);
         187                 :          0 :     return orig_exc;
         188                 :            : }
         189                 :            :
         190                 :            : static PyObject *
         191                 :          0 : test_set_exception(PyObject *self, PyObject *new_exc)
         192                 :            : {
         193                 :          0 :     PyObject *exc = PyErr_GetHandledException();
         194   [ #  #  #  # ]:          0 :     assert(PyExceptionInstance_Check(exc) || exc == NULL);
         195                 :            :
         196                 :          0 :     PyErr_SetHandledException(new_exc);
         197                 :          0 :     return exc;
         198                 :            : }
         199                 :            :
         200                 :            : static PyObject *
         201                 :          0 : test_write_unraisable_exc(PyObject *self, PyObject *args)
         202                 :            : {
         203                 :            :     PyObject *exc, *err_msg, *obj;
         204         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) {
         205                 :          0 :         return NULL;
         206                 :            :     }
         207                 :            :
         208                 :            :     const char *err_msg_utf8;
         209         [ #  # ]:          0 :     if (err_msg != Py_None) {
         210                 :          0 :         err_msg_utf8 = PyUnicode_AsUTF8(err_msg);
         211         [ #  # ]:          0 :         if (err_msg_utf8 == NULL) {
         212                 :          0 :             return NULL;
         213                 :            :         }
         214                 :            :     }
         215                 :            :     else {
         216                 :          0 :         err_msg_utf8 = NULL;
         217                 :            :     }
         218                 :            :
         219                 :          0 :     PyErr_SetObject((PyObject *)Py_TYPE(exc), exc);
         220                 :          0 :     _PyErr_WriteUnraisableMsg(err_msg_utf8, obj);
         221                 :          0 :     Py_RETURN_NONE;
         222                 :            : }
         223                 :            :
         224                 :            : /* To test the format of tracebacks as printed out. */
         225                 :            : static PyObject *
         226                 :          0 : traceback_print(PyObject *self, PyObject *args)
         227                 :            : {
         228                 :            :     PyObject *file;
         229                 :            :     PyObject *traceback;
         230                 :            :
         231         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "OO:traceback_print",
         232                 :            :                             &traceback, &file))
         233                 :            :     {
         234                 :          0 :         return NULL;
         235                 :            :     }
         236                 :            :
         237         [ #  # ]:          0 :     if (PyTraceBack_Print(traceback, file) < 0) {
         238                 :          0 :         return NULL;
         239                 :            :     }
         240                 :          0 :     Py_RETURN_NONE;
         241                 :            : }
         242                 :            :
         243                 :            :
         244                 :            : /*
         245                 :            :  * Define the PyRecurdingInfinitelyError_Type
         246                 :            :  */
         247                 :            :
         248                 :            : static PyTypeObject PyRecursingInfinitelyError_Type;
         249                 :            :
         250                 :            : static int
         251                 :          0 : recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
         252                 :            : {
         253                 :          0 :     PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
         254                 :            :
         255                 :            :     /* Instantiating this exception starts infinite recursion. */
         256                 :          0 :     Py_INCREF(type);
         257                 :          0 :     PyErr_SetObject(type, NULL);
         258                 :          0 :     return -1;
         259                 :            : }
         260                 :            :
         261                 :            : static PyTypeObject PyRecursingInfinitelyError_Type = {
         262                 :            :     .tp_name = "RecursingInfinitelyError",
         263                 :            :     .tp_basicsize = sizeof(PyBaseExceptionObject),
         264                 :            :     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
         265                 :            :     .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."),
         266                 :            :     .tp_init = (initproc)recurse_infinitely_error_init,
         267                 :            : };
         268                 :            :
         269                 :            : static PyMethodDef test_methods[] = {
         270                 :            :     {"err_restore",             err_restore,                     METH_VARARGS},
         271                 :            :     {"err_set_raised",          err_set_raised,                  METH_O},
         272                 :            :     {"exception_print",         exception_print,                 METH_VARARGS},
         273                 :            :     {"fatal_error",             test_fatal_error,                METH_VARARGS,
         274                 :            :      PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")},
         275                 :            :     {"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
         276                 :            :      METH_VARARGS | METH_KEYWORDS},
         277                 :            :     {"exc_set_object",          exc_set_object,                  METH_VARARGS},
         278                 :            :     {"exc_set_object_fetch",    exc_set_object_fetch,            METH_VARARGS},
         279                 :            :     {"raise_exception",         raise_exception,                 METH_VARARGS},
         280                 :            :     {"raise_memoryerror",       raise_memoryerror,               METH_NOARGS},
         281                 :            :     {"set_exc_info",            test_set_exc_info,               METH_VARARGS},
         282                 :            :     {"set_exception",           test_set_exception,              METH_O},
         283                 :            :     {"traceback_print",         traceback_print,                 METH_VARARGS},
         284                 :            :     {"write_unraisable_exc",    test_write_unraisable_exc,       METH_VARARGS},
         285                 :            :     {NULL},
         286                 :            : };
         287                 :            :
         288                 :            : int
         289                 :          2 : _PyTestCapi_Init_Exceptions(PyObject *mod)
         290                 :            : {
         291                 :          2 :     PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
         292         [ -  + ]:          2 :     if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
         293                 :          0 :         return -1;
         294                 :            :     }
         295         [ -  + ]:          2 :     if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError",
         296                 :            :                               (PyObject *)&PyRecursingInfinitelyError_Type) < 0)
         297                 :            :     {
         298                 :          0 :         return -1;
         299                 :            :     }
         300                 :            :
         301         [ -  + ]:          2 :     if (PyModule_AddFunctions(mod, test_methods) < 0) {
         302                 :          0 :         return -1;
         303                 :            :     }
         304                 :            :
         305                 :          2 :     return 0;
         306                 :            : }

Generated by: LCOV version 1.14