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

           Branch data     Line data    Source code
       1                 :            : #define PY_SSIZE_T_CLEAN
       2                 :            : #include "parts.h"
       3                 :            : #include <stddef.h>   // for offsetof()
       4                 :            : 
       5                 :            : 
       6                 :            : // This defines two classes that contain all the simple member types, one
       7                 :            : // using "new" Py_-prefixed API, and the other using "old" <structmember.h>.
       8                 :            : // They should behave identically in Python.
       9                 :            : 
      10                 :            : typedef struct {
      11                 :            :     char bool_member;
      12                 :            :     char byte_member;
      13                 :            :     unsigned char ubyte_member;
      14                 :            :     short short_member;
      15                 :            :     unsigned short ushort_member;
      16                 :            :     int int_member;
      17                 :            :     unsigned int uint_member;
      18                 :            :     long long_member;
      19                 :            :     unsigned long ulong_member;
      20                 :            :     Py_ssize_t pyssizet_member;
      21                 :            :     float float_member;
      22                 :            :     double double_member;
      23                 :            :     char inplace_member[6];
      24                 :            :     long long longlong_member;
      25                 :            :     unsigned long long ulonglong_member;
      26                 :            : } all_structmembers;
      27                 :            : 
      28                 :            : typedef struct {
      29                 :            :     PyObject_HEAD
      30                 :            :     all_structmembers structmembers;
      31                 :            : } test_structmembers;
      32                 :            : 
      33                 :            : 
      34                 :            : static struct PyMemberDef test_members_newapi[] = {
      35                 :            :     {"T_BOOL", Py_T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL},
      36                 :            :     {"T_BYTE", Py_T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL},
      37                 :            :     {"T_UBYTE", Py_T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL},
      38                 :            :     {"T_SHORT", Py_T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL},
      39                 :            :     {"T_USHORT", Py_T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL},
      40                 :            :     {"T_INT", Py_T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL},
      41                 :            :     {"T_UINT", Py_T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
      42                 :            :     {"T_LONG", Py_T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
      43                 :            :     {"T_ULONG", Py_T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
      44                 :            :     {"T_PYSSIZET", Py_T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL},
      45                 :            :     {"T_FLOAT", Py_T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
      46                 :            :     {"T_DOUBLE", Py_T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
      47                 :            :     {"T_STRING_INPLACE", Py_T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL},
      48                 :            :     {"T_LONGLONG", Py_T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL},
      49                 :            :     {"T_ULONGLONG", Py_T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL},
      50                 :            :     {NULL}
      51                 :            : };
      52                 :            : 
      53                 :            : static PyObject *
      54                 :          0 : test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
      55                 :            : {
      56                 :            :     static char *keywords[] = {
      57                 :            :         "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT",
      58                 :            :         "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET",
      59                 :            :         "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE",
      60                 :            :         "T_LONGLONG", "T_ULONGLONG",
      61                 :            :         NULL};
      62                 :            :     static const char fmt[] = "|bbBhHiIlknfds#LK";
      63                 :            :     test_structmembers *ob;
      64                 :          0 :     const char *s = NULL;
      65                 :          0 :     Py_ssize_t string_len = 0;
      66                 :          0 :     ob = PyObject_New(test_structmembers, type);
      67         [ #  # ]:          0 :     if (ob == NULL) {
      68                 :          0 :         return NULL;
      69                 :            :     }
      70                 :          0 :     memset(&ob->structmembers, 0, sizeof(all_structmembers));
      71         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords,
      72                 :            :                                      &ob->structmembers.bool_member,
      73                 :            :                                      &ob->structmembers.byte_member,
      74                 :            :                                      &ob->structmembers.ubyte_member,
      75                 :            :                                      &ob->structmembers.short_member,
      76                 :            :                                      &ob->structmembers.ushort_member,
      77                 :            :                                      &ob->structmembers.int_member,
      78                 :            :                                      &ob->structmembers.uint_member,
      79                 :            :                                      &ob->structmembers.long_member,
      80                 :            :                                      &ob->structmembers.ulong_member,
      81                 :            :                                      &ob->structmembers.pyssizet_member,
      82                 :            :                                      &ob->structmembers.float_member,
      83                 :            :                                      &ob->structmembers.double_member,
      84                 :            :                                      &s, &string_len,
      85                 :            :                                      &ob->structmembers.longlong_member,
      86                 :            :                                      &ob->structmembers.ulonglong_member))
      87                 :            :     {
      88                 :          0 :         Py_DECREF(ob);
      89                 :          0 :         return NULL;
      90                 :            :     }
      91         [ #  # ]:          0 :     if (s != NULL) {
      92         [ #  # ]:          0 :         if (string_len > 5) {
      93                 :          0 :             Py_DECREF(ob);
      94                 :          0 :             PyErr_SetString(PyExc_ValueError, "string too long");
      95                 :          0 :             return NULL;
      96                 :            :         }
      97                 :          0 :         strcpy(ob->structmembers.inplace_member, s);
      98                 :            :     }
      99                 :            :     else {
     100                 :          0 :         strcpy(ob->structmembers.inplace_member, "");
     101                 :            :     }
     102                 :          0 :     return (PyObject *)ob;
     103                 :            : }
     104                 :            : 
     105                 :            : static PyType_Slot test_structmembers_slots[] = {
     106                 :            :     {Py_tp_new, test_structmembers_new},
     107                 :            :     {Py_tp_members, test_members_newapi},
     108                 :            :     {0},
     109                 :            : };
     110                 :            : 
     111                 :            : static PyType_Spec test_structmembers_spec = {
     112                 :            :     .name = "_testcapi._test_structmembersType_NewAPI",
     113                 :            :     .flags = Py_TPFLAGS_DEFAULT,
     114                 :            :     .basicsize = sizeof(test_structmembers),
     115                 :            :     .slots = test_structmembers_slots,
     116                 :            : };
     117                 :            : 
     118                 :            : #include <structmember.h>
     119                 :            : 
     120                 :            : static struct PyMemberDef test_members[] = {
     121                 :            :     {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL},
     122                 :            :     {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL},
     123                 :            :     {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL},
     124                 :            :     {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL},
     125                 :            :     {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL},
     126                 :            :     {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL},
     127                 :            :     {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
     128                 :            :     {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
     129                 :            :     {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
     130                 :            :     {"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL},
     131                 :            :     {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
     132                 :            :     {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
     133                 :            :     {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL},
     134                 :            :     {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL},
     135                 :            :     {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL},
     136                 :            :     {NULL}
     137                 :            : };
     138                 :            : 
     139                 :            : 
     140                 :            : static void
     141                 :          0 : test_structmembers_free(PyObject *ob)
     142                 :            : {
     143                 :          0 :     PyObject_Free(ob);
     144                 :          0 : }
     145                 :            : 
     146                 :            : /* Designated initializers would work too, but this does test the *old* API */
     147                 :            : static PyTypeObject test_structmembersType_OldAPI= {
     148                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
     149                 :            :     "test_structmembersType_OldAPI",
     150                 :            :     sizeof(test_structmembers),         /* tp_basicsize */
     151                 :            :     0,                                  /* tp_itemsize */
     152                 :            :     test_structmembers_free,            /* destructor tp_dealloc */
     153                 :            :     0,                                  /* tp_vectorcall_offset */
     154                 :            :     0,                                  /* tp_getattr */
     155                 :            :     0,                                  /* tp_setattr */
     156                 :            :     0,                                  /* tp_as_async */
     157                 :            :     0,                                  /* tp_repr */
     158                 :            :     0,                                  /* tp_as_number */
     159                 :            :     0,                                  /* tp_as_sequence */
     160                 :            :     0,                                  /* tp_as_mapping */
     161                 :            :     0,                                  /* tp_hash */
     162                 :            :     0,                                  /* tp_call */
     163                 :            :     0,                                  /* tp_str */
     164                 :            :     PyObject_GenericGetAttr,            /* tp_getattro */
     165                 :            :     PyObject_GenericSetAttr,            /* tp_setattro */
     166                 :            :     0,                                  /* tp_as_buffer */
     167                 :            :     0,                                  /* tp_flags */
     168                 :            :     "Type containing all structmember types",
     169                 :            :     0,                                  /* traverseproc tp_traverse */
     170                 :            :     0,                                  /* tp_clear */
     171                 :            :     0,                                  /* tp_richcompare */
     172                 :            :     0,                                  /* tp_weaklistoffset */
     173                 :            :     0,                                  /* tp_iter */
     174                 :            :     0,                                  /* tp_iternext */
     175                 :            :     0,                                  /* tp_methods */
     176                 :            :     test_members,                       /* tp_members */
     177                 :            :     0,
     178                 :            :     0,
     179                 :            :     0,
     180                 :            :     0,
     181                 :            :     0,
     182                 :            :     0,
     183                 :            :     0,
     184                 :            :     0,
     185                 :            :     test_structmembers_new,             /* tp_new */
     186                 :            : };
     187                 :            : 
     188                 :            : 
     189                 :            : int
     190                 :          2 : _PyTestCapi_Init_Structmember(PyObject *m)
     191                 :            : {
     192                 :            :     int res;
     193                 :          2 :     res = PyType_Ready(&test_structmembersType_OldAPI);
     194         [ -  + ]:          2 :     if (res < 0) {
     195                 :          0 :         return -1;
     196                 :            :     }
     197                 :          2 :     res = PyModule_AddObject(
     198                 :            :         m,
     199                 :            :         "_test_structmembersType_OldAPI",
     200                 :            :         (PyObject *)&test_structmembersType_OldAPI);
     201         [ -  + ]:          2 :     if (res < 0) {
     202                 :          0 :         return -1;
     203                 :            :     }
     204                 :            : 
     205                 :          2 :     PyObject *test_structmembersType_NewAPI = PyType_FromModuleAndSpec(
     206                 :            :         m, &test_structmembers_spec, NULL);
     207         [ -  + ]:          2 :     if (!test_structmembersType_NewAPI) {
     208                 :          0 :         return -1;
     209                 :            :     }
     210                 :          2 :     res = PyModule_AddType(m, (PyTypeObject*)test_structmembersType_NewAPI);
     211                 :          2 :     Py_DECREF(test_structmembersType_NewAPI);
     212         [ -  + ]:          2 :     if (res < 0) {
     213                 :          0 :         return -1;
     214                 :            :     }
     215                 :            : 
     216                 :          2 :     return 0;
     217                 :            : }

Generated by: LCOV version 1.14