LCOV - code coverage report
Current view: top level - Objects - cellobject.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 55 68 80.9 %
Date: 2022-07-07 18:19:46 Functions: 10 11 90.9 %

          Line data    Source code
       1             : /* Cell object implementation */
       2             : 
       3             : #include "Python.h"
       4             : #include "pycore_object.h"
       5             : 
       6             : PyObject *
       7     4638440 : PyCell_New(PyObject *obj)
       8             : {
       9             :     PyCellObject *op;
      10             : 
      11     4638440 :     op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
      12     4638440 :     if (op == NULL)
      13           0 :         return NULL;
      14     4638440 :     op->ob_ref = obj;
      15     4638440 :     Py_XINCREF(obj);
      16             : 
      17     4638440 :     _PyObject_GC_TRACK(op);
      18     4638440 :     return (PyObject *)op;
      19             : }
      20             : 
      21             : PyDoc_STRVAR(cell_new_doc,
      22             : "cell([contents])\n"
      23             : "--\n"
      24             : "\n"
      25             : "Create a new cell object.\n"
      26             : "\n"
      27             : "  contents\n"
      28             : "    the contents of the cell. If not specified, the cell will be empty,\n"
      29             : "    and \n further attempts to access its cell_contents attribute will\n"
      30             : "    raise a ValueError.");
      31             : 
      32             : 
      33             : static PyObject *
      34           4 : cell_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
      35             : {
      36           4 :     PyObject *return_value = NULL;
      37           4 :     PyObject *obj = NULL;
      38             : 
      39           4 :     if (!_PyArg_NoKeywords("cell", kwargs)) {
      40           0 :         goto exit;
      41             :     }
      42             :     /* min = 0: we allow the cell to be empty */
      43           4 :     if (!PyArg_UnpackTuple(args, "cell", 0, 1, &obj)) {
      44           0 :         goto exit;
      45             :     }
      46           4 :     return_value = PyCell_New(obj);
      47             : 
      48           4 : exit:
      49           4 :     return return_value;
      50             : }
      51             : 
      52             : PyObject *
      53           0 : PyCell_Get(PyObject *op)
      54             : {
      55           0 :     if (!PyCell_Check(op)) {
      56           0 :         PyErr_BadInternalCall();
      57           0 :         return NULL;
      58             :     }
      59           0 :     PyObject *value = PyCell_GET(op);
      60           0 :     return Py_XNewRef(value);
      61             : }
      62             : 
      63             : int
      64      119485 : PyCell_Set(PyObject *op, PyObject *value)
      65             : {
      66      119485 :     if (!PyCell_Check(op)) {
      67           0 :         PyErr_BadInternalCall();
      68           0 :         return -1;
      69             :     }
      70      119485 :     PyObject *old_value = PyCell_GET(op);
      71      119485 :     Py_XINCREF(value);
      72      119485 :     PyCell_SET(op, value);
      73      119485 :     Py_XDECREF(old_value);
      74      119485 :     return 0;
      75             : }
      76             : 
      77             : static void
      78     4632900 : cell_dealloc(PyCellObject *op)
      79             : {
      80     4632900 :     _PyObject_GC_UNTRACK(op);
      81     4632900 :     Py_XDECREF(op->ob_ref);
      82     4632900 :     PyObject_GC_Del(op);
      83     4632900 : }
      84             : 
      85             : static PyObject *
      86           5 : cell_richcompare(PyObject *a, PyObject *b, int op)
      87             : {
      88             :     /* neither argument should be NULL, unless something's gone wrong */
      89           5 :     assert(a != NULL && b != NULL);
      90             : 
      91             :     /* both arguments should be instances of PyCellObject */
      92           5 :     if (!PyCell_Check(a) || !PyCell_Check(b)) {
      93           0 :         Py_RETURN_NOTIMPLEMENTED;
      94             :     }
      95             : 
      96             :     /* compare cells by contents; empty cells come before anything else */
      97           5 :     a = ((PyCellObject *)a)->ob_ref;
      98           5 :     b = ((PyCellObject *)b)->ob_ref;
      99           5 :     if (a != NULL && b != NULL)
     100           2 :         return PyObject_RichCompare(a, b, op);
     101             : 
     102           3 :     Py_RETURN_RICHCOMPARE(b == NULL, a == NULL, op);
     103             : }
     104             : 
     105             : static PyObject *
     106           2 : cell_repr(PyCellObject *op)
     107             : {
     108           2 :     if (op->ob_ref == NULL)
     109           0 :         return PyUnicode_FromFormat("<cell at %p: empty>", op);
     110             : 
     111           2 :     return PyUnicode_FromFormat("<cell at %p: %.80s object at %p>",
     112           2 :                                op, Py_TYPE(op->ob_ref)->tp_name,
     113             :                                op->ob_ref);
     114             : }
     115             : 
     116             : static int
     117    19380000 : cell_traverse(PyCellObject *op, visitproc visit, void *arg)
     118             : {
     119    19380000 :     Py_VISIT(op->ob_ref);
     120    19380000 :     return 0;
     121             : }
     122             : 
     123             : static int
     124       78126 : cell_clear(PyCellObject *op)
     125             : {
     126       78126 :     Py_CLEAR(op->ob_ref);
     127       78126 :     return 0;
     128             : }
     129             : 
     130             : static PyObject *
     131          15 : cell_get_contents(PyCellObject *op, void *closure)
     132             : {
     133          15 :     if (op->ob_ref == NULL)
     134             :     {
     135           3 :         PyErr_SetString(PyExc_ValueError, "Cell is empty");
     136           3 :         return NULL;
     137             :     }
     138          12 :     Py_INCREF(op->ob_ref);
     139          12 :     return op->ob_ref;
     140             : }
     141             : 
     142             : static int
     143           2 : cell_set_contents(PyCellObject *op, PyObject *obj, void *Py_UNUSED(ignored))
     144             : {
     145           2 :     Py_XINCREF(obj);
     146           2 :     Py_XSETREF(op->ob_ref, obj);
     147           2 :     return 0;
     148             : }
     149             : 
     150             : static PyGetSetDef cell_getsetlist[] = {
     151             :     {"cell_contents", (getter)cell_get_contents,
     152             :                       (setter)cell_set_contents, NULL},
     153             :     {NULL} /* sentinel */
     154             : };
     155             : 
     156             : PyTypeObject PyCell_Type = {
     157             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     158             :     "cell",
     159             :     sizeof(PyCellObject),
     160             :     0,
     161             :     (destructor)cell_dealloc,                   /* tp_dealloc */
     162             :     0,                                          /* tp_vectorcall_offset */
     163             :     0,                                          /* tp_getattr */
     164             :     0,                                          /* tp_setattr */
     165             :     0,                                          /* tp_as_async */
     166             :     (reprfunc)cell_repr,                        /* tp_repr */
     167             :     0,                                          /* tp_as_number */
     168             :     0,                                          /* tp_as_sequence */
     169             :     0,                                          /* tp_as_mapping */
     170             :     0,                                          /* tp_hash */
     171             :     0,                                          /* tp_call */
     172             :     0,                                          /* tp_str */
     173             :     PyObject_GenericGetAttr,                    /* tp_getattro */
     174             :     0,                                          /* tp_setattro */
     175             :     0,                                          /* tp_as_buffer */
     176             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
     177             :     cell_new_doc,                               /* tp_doc */
     178             :     (traverseproc)cell_traverse,                /* tp_traverse */
     179             :     (inquiry)cell_clear,                        /* tp_clear */
     180             :     cell_richcompare,                           /* tp_richcompare */
     181             :     0,                                          /* tp_weaklistoffset */
     182             :     0,                                          /* tp_iter */
     183             :     0,                                          /* tp_iternext */
     184             :     0,                                          /* tp_methods */
     185             :     0,                                          /* tp_members */
     186             :     cell_getsetlist,                            /* tp_getset */
     187             :     0,                                          /* tp_base */
     188             :     0,                                          /* tp_dict */
     189             :     0,                                          /* tp_descr_get */
     190             :     0,                                          /* tp_descr_set */
     191             :     0,                                          /* tp_dictoffset */
     192             :     0,                                          /* tp_init */
     193             :     0,                                          /* tp_alloc */
     194             :     (newfunc)cell_new,                          /* tp_new */
     195             :     0,                                          /* tp_free */
     196             : };

Generated by: LCOV version 1.14