Home | History | Annotate | Download | only in Objects
      1 /* Cell object implementation */
      2 
      3 #include "Python.h"
      4 
      5 PyObject *
      6 PyCell_New(PyObject *obj)
      7 {
      8     PyCellObject *op;
      9 
     10     op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
     11     if (op == NULL)
     12         return NULL;
     13     op->ob_ref = obj;
     14     Py_XINCREF(obj);
     15 
     16     _PyObject_GC_TRACK(op);
     17     return (PyObject *)op;
     18 }
     19 
     20 PyObject *
     21 PyCell_Get(PyObject *op)
     22 {
     23     if (!PyCell_Check(op)) {
     24         PyErr_BadInternalCall();
     25         return NULL;
     26     }
     27     Py_XINCREF(((PyCellObject*)op)->ob_ref);
     28     return PyCell_GET(op);
     29 }
     30 
     31 int
     32 PyCell_Set(PyObject *op, PyObject *obj)
     33 {
     34     PyObject* oldobj;
     35     if (!PyCell_Check(op)) {
     36         PyErr_BadInternalCall();
     37         return -1;
     38     }
     39     oldobj = PyCell_GET(op);
     40     Py_XINCREF(obj);
     41     PyCell_SET(op, obj);
     42     Py_XDECREF(oldobj);
     43     return 0;
     44 }
     45 
     46 static void
     47 cell_dealloc(PyCellObject *op)
     48 {
     49     _PyObject_GC_UNTRACK(op);
     50     Py_XDECREF(op->ob_ref);
     51     PyObject_GC_Del(op);
     52 }
     53 
     54 static int
     55 cell_compare(PyCellObject *a, PyCellObject *b)
     56 {
     57     /* Py3K warning for comparisons  */
     58     if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
     59                        1) < 0) {
     60         return -2;
     61     }
     62 
     63     if (a->ob_ref == NULL) {
     64         if (b->ob_ref == NULL)
     65             return 0;
     66         return -1;
     67     } else if (b->ob_ref == NULL)
     68         return 1;
     69     return PyObject_Compare(a->ob_ref, b->ob_ref);
     70 }
     71 
     72 static PyObject *
     73 cell_repr(PyCellObject *op)
     74 {
     75     if (op->ob_ref == NULL)
     76         return PyString_FromFormat("<cell at %p: empty>", op);
     77 
     78     return PyString_FromFormat("<cell at %p: %.80s object at %p>",
     79                                op, op->ob_ref->ob_type->tp_name,
     80                                op->ob_ref);
     81 }
     82 
     83 static int
     84 cell_traverse(PyCellObject *op, visitproc visit, void *arg)
     85 {
     86     Py_VISIT(op->ob_ref);
     87     return 0;
     88 }
     89 
     90 static int
     91 cell_clear(PyCellObject *op)
     92 {
     93     Py_CLEAR(op->ob_ref);
     94     return 0;
     95 }
     96 
     97 static PyObject *
     98 cell_get_contents(PyCellObject *op, void *closure)
     99 {
    100     if (op->ob_ref == NULL)
    101     {
    102         PyErr_SetString(PyExc_ValueError, "Cell is empty");
    103         return NULL;
    104     }
    105     Py_INCREF(op->ob_ref);
    106     return op->ob_ref;
    107 }
    108 
    109 static PyGetSetDef cell_getsetlist[] = {
    110     {"cell_contents", (getter)cell_get_contents, NULL},
    111     {NULL} /* sentinel */
    112 };
    113 
    114 PyTypeObject PyCell_Type = {
    115     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    116     "cell",
    117     sizeof(PyCellObject),
    118     0,
    119     (destructor)cell_dealloc,               /* tp_dealloc */
    120     0,                                      /* tp_print */
    121     0,                                          /* tp_getattr */
    122     0,                                          /* tp_setattr */
    123     (cmpfunc)cell_compare,                      /* tp_compare */
    124     (reprfunc)cell_repr,                        /* tp_repr */
    125     0,                                          /* tp_as_number */
    126     0,                                          /* tp_as_sequence */
    127     0,                                          /* tp_as_mapping */
    128     0,                                          /* tp_hash */
    129     0,                                          /* tp_call */
    130     0,                                          /* tp_str */
    131     PyObject_GenericGetAttr,                    /* tp_getattro */
    132     0,                                          /* tp_setattro */
    133     0,                                          /* tp_as_buffer */
    134     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
    135     0,                                          /* tp_doc */
    136     (traverseproc)cell_traverse,                /* tp_traverse */
    137     (inquiry)cell_clear,                        /* tp_clear */
    138     0,                                          /* tp_richcompare */
    139     0,                                          /* tp_weaklistoffset */
    140     0,                                          /* tp_iter */
    141     0,                                          /* tp_iternext */
    142     0,                                          /* tp_methods */
    143     0,                                          /* tp_members */
    144     cell_getsetlist,                            /* tp_getset */
    145 };
    146