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