LCOV - code coverage report
Current view: top level - Objects - cellobject.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 54 67 80.6 %
Date: 2022-07-20 13:12:14 Functions: 10 11 90.9 %
Branches: 25 49 51.0 %

           Branch data     Line data    Source code
       1                 :            : /* Cell object implementation */
       2                 :            : 
       3                 :            : #include "Python.h"
       4                 :            : #include "pycore_object.h"
       5                 :            : 
       6                 :            : PyObject *
       7                 :    4526566 : PyCell_New(PyObject *obj)
       8                 :            : {
       9                 :            :     PyCellObject *op;
      10                 :            : 
      11                 :    4526566 :     op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
      12         [ -  + ]:    4526566 :     if (op == NULL)
      13                 :          0 :         return NULL;
      14                 :    4526566 :     op->ob_ref = obj;
      15                 :    4526566 :     Py_XINCREF(obj);
      16                 :            : 
      17                 :    4526566 :     _PyObject_GC_TRACK(op);
      18                 :    4526566 :     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                 :     118472 : PyCell_Set(PyObject *op, PyObject *value)
      65                 :            : {
      66         [ -  + ]:     118472 :     if (!PyCell_Check(op)) {
      67                 :          0 :         PyErr_BadInternalCall();
      68                 :          0 :         return -1;
      69                 :            :     }
      70                 :     118472 :     PyObject *old_value = PyCell_GET(op);
      71                 :     118472 :     Py_XINCREF(value);
      72                 :     118472 :     PyCell_SET(op, value);
      73                 :     118472 :     Py_XDECREF(old_value);
      74                 :     118472 :     return 0;
      75                 :            : }
      76                 :            : 
      77                 :            : static void
      78                 :    4520377 : cell_dealloc(PyCellObject *op)
      79                 :            : {
      80                 :    4520377 :     _PyObject_GC_UNTRACK(op);
      81                 :    4520377 :     Py_XDECREF(op->ob_ref);
      82                 :    4520377 :     PyObject_GC_Del(op);
      83                 :    4520377 : }
      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                 :            :     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                 :   18693163 : cell_traverse(PyCellObject *op, visitproc visit, void *arg)
     118                 :            : {
     119   [ +  +  +  + ]:   18693163 :     Py_VISIT(op->ob_ref);
     120                 :   18693162 :     return 0;
     121                 :            : }
     122                 :            : 
     123                 :            : static int
     124                 :      77612 : cell_clear(PyCellObject *op)
     125                 :            : {
     126         [ +  + ]:      77612 :     Py_CLEAR(op->ob_ref);
     127                 :      77612 :     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