LCOV - code coverage report
Current view: top level - Modules/_testcapi - code.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 3 67 4.5 %
Date: 2023-03-20 08:15:36 Functions: 1 3 33.3 %
Branches: 1 42 2.4 %

           Branch data     Line data    Source code
       1                 :            : #include "parts.h"
       2                 :            : 
       3                 :            : static Py_ssize_t
       4                 :          0 : get_code_extra_index(PyInterpreterState* interp) {
       5                 :          0 :     Py_ssize_t result = -1;
       6                 :            : 
       7                 :            :     static const char *key = "_testcapi.frame_evaluation.code_index";
       8                 :            : 
       9                 :          0 :     PyObject *interp_dict = PyInterpreterState_GetDict(interp); // borrowed
      10         [ #  # ]:          0 :     assert(interp_dict);  // real users would handle missing dict... somehow
      11                 :            : 
      12                 :          0 :     PyObject *index_obj = PyDict_GetItemString(interp_dict, key); // borrowed
      13                 :          0 :     Py_ssize_t index = 0;
      14         [ #  # ]:          0 :     if (!index_obj) {
      15         [ #  # ]:          0 :         if (PyErr_Occurred()) {
      16                 :          0 :             goto finally;
      17                 :            :         }
      18                 :          0 :         index = PyUnstable_Eval_RequestCodeExtraIndex(NULL);
      19   [ #  #  #  # ]:          0 :         if (index < 0 || PyErr_Occurred()) {
      20                 :          0 :             goto finally;
      21                 :            :         }
      22                 :          0 :         index_obj = PyLong_FromSsize_t(index); // strong ref
      23         [ #  # ]:          0 :         if (!index_obj) {
      24                 :          0 :             goto finally;
      25                 :            :         }
      26                 :          0 :         int res = PyDict_SetItemString(interp_dict, key, index_obj);
      27                 :          0 :         Py_DECREF(index_obj);
      28         [ #  # ]:          0 :         if (res < 0) {
      29                 :          0 :             goto finally;
      30                 :            :         }
      31                 :            :     }
      32                 :            :     else {
      33                 :          0 :         index = PyLong_AsSsize_t(index_obj);
      34   [ #  #  #  # ]:          0 :         if (index == -1 && PyErr_Occurred()) {
      35                 :          0 :             goto finally;
      36                 :            :         }
      37                 :            :     }
      38                 :            : 
      39                 :          0 :     result = index;
      40                 :          0 : finally:
      41                 :          0 :     return result;
      42                 :            : }
      43                 :            : 
      44                 :            : static PyObject *
      45                 :          0 : test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
      46                 :            : {
      47                 :          0 :     PyObject *result = NULL;
      48                 :          0 :     PyObject *test_module = NULL;
      49                 :          0 :     PyObject *test_func = NULL;
      50                 :            : 
      51                 :            :     // Get or initialize interpreter-specific code object storage index
      52                 :          0 :     PyInterpreterState *interp = PyInterpreterState_Get();
      53         [ #  # ]:          0 :     if (!interp) {
      54                 :          0 :         return NULL;
      55                 :            :     }
      56                 :          0 :     Py_ssize_t code_extra_index = get_code_extra_index(interp);
      57         [ #  # ]:          0 :     if (PyErr_Occurred()) {
      58                 :          0 :         goto finally;
      59                 :            :     }
      60                 :            : 
      61                 :            :     // Get a function to test with
      62                 :            :     // This can be any Python function. Use `test.test_misc.testfunction`.
      63                 :          0 :     test_module = PyImport_ImportModule("test.test_capi.test_misc");
      64         [ #  # ]:          0 :     if (!test_module) {
      65                 :          0 :         goto finally;
      66                 :            :     }
      67                 :          0 :     test_func = PyObject_GetAttrString(test_module, "testfunction");
      68         [ #  # ]:          0 :     if (!test_func) {
      69                 :          0 :         goto finally;
      70                 :            :     }
      71                 :          0 :     PyObject *test_func_code = PyFunction_GetCode(test_func);  // borrowed
      72         [ #  # ]:          0 :     if (!test_func_code) {
      73                 :          0 :         goto finally;
      74                 :            :     }
      75                 :            : 
      76                 :            :     // Check the value is initially NULL
      77                 :            :     void *extra;
      78                 :          0 :     int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
      79         [ #  # ]:          0 :     if (res < 0) {
      80                 :          0 :         goto finally;
      81                 :            :     }
      82         [ #  # ]:          0 :     assert (extra == NULL);
      83                 :            : 
      84                 :            :     // Set another code extra value
      85                 :          0 :     res = PyUnstable_Code_SetExtra(test_func_code, code_extra_index, (void*)(uintptr_t)77);
      86         [ #  # ]:          0 :     if (res < 0) {
      87                 :          0 :         goto finally;
      88                 :            :     }
      89                 :            :     // Assert it was set correctly
      90                 :          0 :     res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
      91         [ #  # ]:          0 :     if (res < 0) {
      92                 :          0 :         goto finally;
      93                 :            :     }
      94         [ #  # ]:          0 :     assert ((uintptr_t)extra == 77);
      95                 :            :     // Revert to initial code extra value.
      96                 :          0 :     res = PyUnstable_Code_SetExtra(test_func_code, code_extra_index, NULL);
      97         [ #  # ]:          0 :     if (res < 0) {
      98                 :          0 :         goto finally;
      99                 :            :     }
     100                 :          0 :     result = Py_NewRef(Py_None);
     101                 :          0 : finally:
     102                 :          0 :     Py_XDECREF(test_module);
     103                 :          0 :     Py_XDECREF(test_func);
     104                 :          0 :     return result;
     105                 :            : }
     106                 :            : 
     107                 :            : static PyMethodDef TestMethods[] = {
     108                 :            :     {"test_code_extra", test_code_extra, METH_NOARGS},
     109                 :            :     {NULL},
     110                 :            : };
     111                 :            : 
     112                 :            : int
     113                 :          2 : _PyTestCapi_Init_Code(PyObject *m) {
     114         [ -  + ]:          2 :     if (PyModule_AddFunctions(m, TestMethods) < 0) {
     115                 :          0 :         return -1;
     116                 :            :     }
     117                 :            : 
     118                 :          2 :     return 0;
     119                 :            : }

Generated by: LCOV version 1.14