LCOV - code coverage report
Current view: top level - Modules - xxsubtype.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 0 78 0.0 %
Date: 2017-04-19 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #include "Python.h"
       2             : #include "structmember.h"
       3             : 
       4             : PyDoc_STRVAR(xxsubtype__doc__,
       5             : "xxsubtype is an example module showing how to subtype builtin types from C.\n"
       6             : "test_descr.py in the standard test suite requires it in order to complete.\n"
       7             : "If you don't care about the examples, and don't intend to run the Python\n"
       8             : "test suite, you can recompile Python without Modules/xxsubtype.c.");
       9             : 
      10             : /* We link this module statically for convenience.  If compiled as a shared
      11             :    library instead, some compilers don't allow addresses of Python objects
      12             :    defined in other libraries to be used in static initializers here.  The
      13             :    DEFERRED_ADDRESS macro is used to tag the slots where such addresses
      14             :    appear; the module init function must fill in the tagged slots at runtime.
      15             :    The argument is for documentation -- the macro ignores it.
      16             : */
      17             : #define DEFERRED_ADDRESS(ADDR) 0
      18             : 
      19             : /* spamlist -- a list subtype */
      20             : 
      21             : typedef struct {
      22             :     PyListObject list;
      23             :     int state;
      24             : } spamlistobject;
      25             : 
      26             : static PyObject *
      27           0 : spamlist_getstate(spamlistobject *self, PyObject *args)
      28             : {
      29           0 :     if (!PyArg_ParseTuple(args, ":getstate"))
      30           0 :         return NULL;
      31           0 :     return PyInt_FromLong(self->state);
      32             : }
      33             : 
      34             : static PyObject *
      35           0 : spamlist_setstate(spamlistobject *self, PyObject *args)
      36             : {
      37             :     int state;
      38             : 
      39           0 :     if (!PyArg_ParseTuple(args, "i:setstate", &state))
      40           0 :         return NULL;
      41           0 :     self->state = state;
      42           0 :     Py_INCREF(Py_None);
      43           0 :     return Py_None;
      44             : }
      45             : 
      46             : static PyObject *
      47           0 : spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw)
      48             : {
      49           0 :     PyObject *result = PyTuple_New(3);
      50             : 
      51           0 :     if (result != NULL) {
      52           0 :         if (self == NULL)
      53           0 :             self = Py_None;
      54           0 :         if (kw == NULL)
      55           0 :             kw = Py_None;
      56           0 :         Py_INCREF(self);
      57           0 :         PyTuple_SET_ITEM(result, 0, self);
      58           0 :         Py_INCREF(args);
      59           0 :         PyTuple_SET_ITEM(result, 1, args);
      60           0 :         Py_INCREF(kw);
      61           0 :         PyTuple_SET_ITEM(result, 2, kw);
      62             :     }
      63           0 :     return result;
      64             : }
      65             : 
      66             : static PyMethodDef spamlist_methods[] = {
      67             :     {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
      68             :         PyDoc_STR("getstate() -> state")},
      69             :     {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
      70             :         PyDoc_STR("setstate(state)")},
      71             :     /* These entries differ only in the flags; they are used by the tests
      72             :        in test.test_descr. */
      73             :     {"classmeth", (PyCFunction)spamlist_specialmeth,
      74             :         METH_VARARGS | METH_KEYWORDS | METH_CLASS,
      75             :         PyDoc_STR("classmeth(*args, **kw)")},
      76             :     {"staticmeth", (PyCFunction)spamlist_specialmeth,
      77             :         METH_VARARGS | METH_KEYWORDS | METH_STATIC,
      78             :         PyDoc_STR("staticmeth(*args, **kw)")},
      79             :     {NULL,      NULL},
      80             : };
      81             : 
      82             : static int
      83           0 : spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
      84             : {
      85           0 :     if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
      86           0 :         return -1;
      87           0 :     self->state = 0;
      88           0 :     return 0;
      89             : }
      90             : 
      91             : static PyObject *
      92           0 : spamlist_state_get(spamlistobject *self)
      93             : {
      94           0 :     return PyInt_FromLong(self->state);
      95             : }
      96             : 
      97             : static PyGetSetDef spamlist_getsets[] = {
      98             :     {"state", (getter)spamlist_state_get, NULL,
      99             :      PyDoc_STR("an int variable for demonstration purposes")},
     100             :     {0}
     101             : };
     102             : 
     103             : static PyTypeObject spamlist_type = {
     104             :     PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
     105             :     "xxsubtype.spamlist",
     106             :     sizeof(spamlistobject),
     107             :     0,
     108             :     0,                                          /* tp_dealloc */
     109             :     0,                                          /* tp_print */
     110             :     0,                                          /* tp_getattr */
     111             :     0,                                          /* tp_setattr */
     112             :     0,                                          /* tp_compare */
     113             :     0,                                          /* tp_repr */
     114             :     0,                                          /* tp_as_number */
     115             :     0,                                          /* tp_as_sequence */
     116             :     0,                                          /* tp_as_mapping */
     117             :     0,                                          /* tp_hash */
     118             :     0,                                          /* tp_call */
     119             :     0,                                          /* tp_str */
     120             :     0,                                          /* tp_getattro */
     121             :     0,                                          /* tp_setattro */
     122             :     0,                                          /* tp_as_buffer */
     123             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     124             :     0,                                          /* tp_doc */
     125             :     0,                                          /* tp_traverse */
     126             :     0,                                          /* tp_clear */
     127             :     0,                                          /* tp_richcompare */
     128             :     0,                                          /* tp_weaklistoffset */
     129             :     0,                                          /* tp_iter */
     130             :     0,                                          /* tp_iternext */
     131             :     spamlist_methods,                           /* tp_methods */
     132             :     0,                                          /* tp_members */
     133             :     spamlist_getsets,                           /* tp_getset */
     134             :     DEFERRED_ADDRESS(&PyList_Type),             /* tp_base */
     135             :     0,                                          /* tp_dict */
     136             :     0,                                          /* tp_descr_get */
     137             :     0,                                          /* tp_descr_set */
     138             :     0,                                          /* tp_dictoffset */
     139             :     (initproc)spamlist_init,                    /* tp_init */
     140             :     0,                                          /* tp_alloc */
     141             :     0,                                          /* tp_new */
     142             : };
     143             : 
     144             : /* spamdict -- a dict subtype */
     145             : 
     146             : typedef struct {
     147             :     PyDictObject dict;
     148             :     int state;
     149             : } spamdictobject;
     150             : 
     151             : static PyObject *
     152           0 : spamdict_getstate(spamdictobject *self, PyObject *args)
     153             : {
     154           0 :     if (!PyArg_ParseTuple(args, ":getstate"))
     155           0 :         return NULL;
     156           0 :     return PyInt_FromLong(self->state);
     157             : }
     158             : 
     159             : static PyObject *
     160           0 : spamdict_setstate(spamdictobject *self, PyObject *args)
     161             : {
     162             :     int state;
     163             : 
     164           0 :     if (!PyArg_ParseTuple(args, "i:setstate", &state))
     165           0 :         return NULL;
     166           0 :     self->state = state;
     167           0 :     Py_INCREF(Py_None);
     168           0 :     return Py_None;
     169             : }
     170             : 
     171             : static PyMethodDef spamdict_methods[] = {
     172             :     {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
     173             :         PyDoc_STR("getstate() -> state")},
     174             :     {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
     175             :         PyDoc_STR("setstate(state)")},
     176             :     {NULL,      NULL},
     177             : };
     178             : 
     179             : static int
     180           0 : spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
     181             : {
     182           0 :     if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
     183           0 :         return -1;
     184           0 :     self->state = 0;
     185           0 :     return 0;
     186             : }
     187             : 
     188             : static PyMemberDef spamdict_members[] = {
     189             :     {"state", T_INT, offsetof(spamdictobject, state), READONLY,
     190             :      PyDoc_STR("an int variable for demonstration purposes")},
     191             :     {0}
     192             : };
     193             : 
     194             : static PyTypeObject spamdict_type = {
     195             :     PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
     196             :     "xxsubtype.spamdict",
     197             :     sizeof(spamdictobject),
     198             :     0,
     199             :     0,                                          /* tp_dealloc */
     200             :     0,                                          /* tp_print */
     201             :     0,                                          /* tp_getattr */
     202             :     0,                                          /* tp_setattr */
     203             :     0,                                          /* tp_compare */
     204             :     0,                                          /* tp_repr */
     205             :     0,                                          /* tp_as_number */
     206             :     0,                                          /* tp_as_sequence */
     207             :     0,                                          /* tp_as_mapping */
     208             :     0,                                          /* tp_hash */
     209             :     0,                                          /* tp_call */
     210             :     0,                                          /* tp_str */
     211             :     0,                                          /* tp_getattro */
     212             :     0,                                          /* tp_setattro */
     213             :     0,                                          /* tp_as_buffer */
     214             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     215             :     0,                                          /* tp_doc */
     216             :     0,                                          /* tp_traverse */
     217             :     0,                                          /* tp_clear */
     218             :     0,                                          /* tp_richcompare */
     219             :     0,                                          /* tp_weaklistoffset */
     220             :     0,                                          /* tp_iter */
     221             :     0,                                          /* tp_iternext */
     222             :     spamdict_methods,                           /* tp_methods */
     223             :     spamdict_members,                           /* tp_members */
     224             :     0,                                          /* tp_getset */
     225             :     DEFERRED_ADDRESS(&PyDict_Type),             /* tp_base */
     226             :     0,                                          /* tp_dict */
     227             :     0,                                          /* tp_descr_get */
     228             :     0,                                          /* tp_descr_set */
     229             :     0,                                          /* tp_dictoffset */
     230             :     (initproc)spamdict_init,                    /* tp_init */
     231             :     0,                                          /* tp_alloc */
     232             :     0,                                          /* tp_new */
     233             : };
     234             : 
     235             : static PyObject *
     236           0 : spam_bench(PyObject *self, PyObject *args)
     237             : {
     238             :     PyObject *obj, *name, *res;
     239           0 :     int n = 1000;
     240             :     time_t t0, t1;
     241             : 
     242           0 :     if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
     243           0 :         return NULL;
     244           0 :     t0 = clock();
     245           0 :     while (--n >= 0) {
     246           0 :         res = PyObject_GetAttr(obj, name);
     247           0 :         if (res == NULL)
     248           0 :             return NULL;
     249           0 :         Py_DECREF(res);
     250             :     }
     251           0 :     t1 = clock();
     252           0 :     return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
     253             : }
     254             : 
     255             : static PyMethodDef xxsubtype_functions[] = {
     256             :     {"bench",           spam_bench,     METH_VARARGS},
     257             :     {NULL,              NULL}           /* sentinel */
     258             : };
     259             : 
     260             : PyMODINIT_FUNC
     261           0 : initxxsubtype(void)
     262             : {
     263             :     PyObject *m;
     264             : 
     265             :     /* Fill in deferred data addresses.  This must be done before
     266             :        PyType_Ready() is called.  Note that PyType_Ready() automatically
     267             :        initializes the ob.ob_type field to &PyType_Type if it's NULL,
     268             :        so it's not necessary to fill in ob_type first. */
     269           0 :     spamdict_type.tp_base = &PyDict_Type;
     270           0 :     if (PyType_Ready(&spamdict_type) < 0)
     271           0 :         return;
     272             : 
     273           0 :     spamlist_type.tp_base = &PyList_Type;
     274           0 :     if (PyType_Ready(&spamlist_type) < 0)
     275           0 :         return;
     276             : 
     277           0 :     m = Py_InitModule3("xxsubtype",
     278             :                        xxsubtype_functions,
     279             :                        xxsubtype__doc__);
     280           0 :     if (m == NULL)
     281           0 :         return;
     282             : 
     283           0 :     if (PyType_Ready(&spamlist_type) < 0)
     284           0 :         return;
     285           0 :     if (PyType_Ready(&spamdict_type) < 0)
     286           0 :         return;
     287             : 
     288           0 :     Py_INCREF(&spamlist_type);
     289           0 :     if (PyModule_AddObject(m, "spamlist",
     290             :                            (PyObject *) &spamlist_type) < 0)
     291           0 :         return;
     292             : 
     293           0 :     Py_INCREF(&spamdict_type);
     294           0 :     if (PyModule_AddObject(m, "spamdict",
     295             :                            (PyObject *) &spamdict_type) < 0)
     296           0 :         return;
     297             : }

Generated by: LCOV version 1.10