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