blob: 7b05e61ce46fa0c68bda9dc2370c610209636db0 [file] [log] [blame]
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +00001/* Cell object implementation */
2
3#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -06004#include "internal/mem.h"
5#include "internal/pystate.h"
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +00006
7PyObject *
8PyCell_New(PyObject *obj)
9{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000010 PyCellObject *op;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000012 op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
13 if (op == NULL)
14 return NULL;
15 op->ob_ref = obj;
16 Py_XINCREF(obj);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000018 _PyObject_GC_TRACK(op);
19 return (PyObject *)op;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000020}
21
22PyObject *
23PyCell_Get(PyObject *op)
24{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025 if (!PyCell_Check(op)) {
26 PyErr_BadInternalCall();
27 return NULL;
28 }
29 Py_XINCREF(((PyCellObject*)op)->ob_ref);
30 return PyCell_GET(op);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000031}
32
33int
34PyCell_Set(PyObject *op, PyObject *obj)
35{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 PyObject* oldobj;
37 if (!PyCell_Check(op)) {
38 PyErr_BadInternalCall();
39 return -1;
40 }
41 oldobj = PyCell_GET(op);
42 Py_XINCREF(obj);
43 PyCell_SET(op, obj);
44 Py_XDECREF(oldobj);
45 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000046}
47
48static void
49cell_dealloc(PyCellObject *op)
50{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 _PyObject_GC_UNTRACK(op);
52 Py_XDECREF(op->ob_ref);
53 PyObject_GC_Del(op);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000054}
55
Mark Dickinson211c6252009-02-01 10:28:51 +000056static PyObject *
57cell_richcompare(PyObject *a, PyObject *b, int op)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000058{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 /* neither argument should be NULL, unless something's gone wrong */
60 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +000061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062 /* both arguments should be instances of PyCellObject */
63 if (!PyCell_Check(a) || !PyCell_Check(b)) {
stratakise8b19652017-11-02 11:32:54 +010064 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 }
Mark Dickinson211c6252009-02-01 10:28:51 +000066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 /* compare cells by contents; empty cells come before anything else */
68 a = ((PyCellObject *)a)->ob_ref;
69 b = ((PyCellObject *)b)->ob_ref;
70 if (a != NULL && b != NULL)
71 return PyObject_RichCompare(a, b, op);
Mark Dickinson211c6252009-02-01 10:28:51 +000072
stratakise8b19652017-11-02 11:32:54 +010073 Py_RETURN_RICHCOMPARE(b == NULL, a == NULL, op);
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000074}
75
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000076static PyObject *
77cell_repr(PyCellObject *op)
78{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 if (op->ob_ref == NULL)
80 return PyUnicode_FromFormat("<cell at %p: empty>", op);
Barry Warsaw7ce36942001-08-24 18:34:26 +000081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 return PyUnicode_FromFormat("<cell at %p: %.80s object at %p>",
83 op, op->ob_ref->ob_type->tp_name,
84 op->ob_ref);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000085}
86
87static int
88cell_traverse(PyCellObject *op, visitproc visit, void *arg)
89{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 Py_VISIT(op->ob_ref);
91 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000092}
93
94static int
95cell_clear(PyCellObject *op)
96{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 Py_CLEAR(op->ob_ref);
98 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000099}
100
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000101static PyObject *
102cell_get_contents(PyCellObject *op, void *closure)
103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 if (op->ob_ref == NULL)
105 {
106 PyErr_SetString(PyExc_ValueError, "Cell is empty");
107 return NULL;
108 }
109 Py_INCREF(op->ob_ref);
110 return op->ob_ref;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000111}
112
Victor Stinner0ad05c32017-09-20 06:54:13 -0700113static int
Lisa Roach64505a12017-06-08 04:43:26 -0700114cell_set_contents(PyCellObject *op, PyObject *obj)
115{
116 Py_XINCREF(obj);
117 Py_XSETREF(op->ob_ref, obj);
118 return 0;
119}
120
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000121static PyGetSetDef cell_getsetlist[] = {
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +0300122 {"cell_contents", (getter)cell_get_contents,
Lisa Roach64505a12017-06-08 04:43:26 -0700123 (setter)cell_set_contents, NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 {NULL} /* sentinel */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000125};
126
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +0000127PyTypeObject PyCell_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 PyVarObject_HEAD_INIT(&PyType_Type, 0)
129 "cell",
130 sizeof(PyCellObject),
131 0,
Benjamin Peterson07451dd2016-05-12 23:12:21 -0700132 (destructor)cell_dealloc, /* tp_dealloc */
133 0, /* tp_print */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 0, /* tp_getattr */
135 0, /* tp_setattr */
136 0, /* tp_reserved */
137 (reprfunc)cell_repr, /* tp_repr */
138 0, /* tp_as_number */
139 0, /* tp_as_sequence */
140 0, /* tp_as_mapping */
141 0, /* tp_hash */
142 0, /* tp_call */
143 0, /* tp_str */
144 PyObject_GenericGetAttr, /* tp_getattro */
145 0, /* tp_setattro */
146 0, /* tp_as_buffer */
Benjamin Peterson07451dd2016-05-12 23:12:21 -0700147 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 0, /* tp_doc */
149 (traverseproc)cell_traverse, /* tp_traverse */
150 (inquiry)cell_clear, /* tp_clear */
151 cell_richcompare, /* tp_richcompare */
152 0, /* tp_weaklistoffset */
153 0, /* tp_iter */
154 0, /* tp_iternext */
155 0, /* tp_methods */
156 0, /* tp_members */
157 cell_getsetlist, /* tp_getset */
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +0000158};