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