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