blob: 6b7136c41270607a428f812a6026732337fe117b [file] [log] [blame]
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +00001/* Cell object implementation */
2
3#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01004#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01005#include "pycore_pymem.h"
6#include "pycore_pystate.h"
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +00007
8PyObject *
9PyCell_New(PyObject *obj)
10{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000011 PyCellObject *op;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
14 if (op == NULL)
15 return NULL;
16 op->ob_ref = obj;
17 Py_XINCREF(obj);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019 _PyObject_GC_TRACK(op);
20 return (PyObject *)op;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000021}
22
23PyObject *
24PyCell_Get(PyObject *op)
25{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000026 if (!PyCell_Check(op)) {
27 PyErr_BadInternalCall();
28 return NULL;
29 }
30 Py_XINCREF(((PyCellObject*)op)->ob_ref);
31 return PyCell_GET(op);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000032}
33
34int
35PyCell_Set(PyObject *op, PyObject *obj)
36{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 PyObject* oldobj;
38 if (!PyCell_Check(op)) {
39 PyErr_BadInternalCall();
40 return -1;
41 }
42 oldobj = PyCell_GET(op);
43 Py_XINCREF(obj);
44 PyCell_SET(op, obj);
45 Py_XDECREF(oldobj);
46 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000047}
48
49static void
50cell_dealloc(PyCellObject *op)
51{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052 _PyObject_GC_UNTRACK(op);
53 Py_XDECREF(op->ob_ref);
54 PyObject_GC_Del(op);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000055}
56
Mark Dickinson211c6252009-02-01 10:28:51 +000057static PyObject *
58cell_richcompare(PyObject *a, PyObject *b, int op)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 /* neither argument should be NULL, unless something's gone wrong */
61 assert(a != NULL && b != NULL);
Mark Dickinson211c6252009-02-01 10:28:51 +000062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 /* both arguments should be instances of PyCellObject */
64 if (!PyCell_Check(a) || !PyCell_Check(b)) {
stratakise8b19652017-11-02 11:32:54 +010065 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 }
Mark Dickinson211c6252009-02-01 10:28:51 +000067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 /* compare cells by contents; empty cells come before anything else */
69 a = ((PyCellObject *)a)->ob_ref;
70 b = ((PyCellObject *)b)->ob_ref;
71 if (a != NULL && b != NULL)
72 return PyObject_RichCompare(a, b, op);
Mark Dickinson211c6252009-02-01 10:28:51 +000073
stratakise8b19652017-11-02 11:32:54 +010074 Py_RETURN_RICHCOMPARE(b == NULL, a == NULL, op);
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000075}
76
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000077static PyObject *
78cell_repr(PyCellObject *op)
79{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 if (op->ob_ref == NULL)
81 return PyUnicode_FromFormat("<cell at %p: empty>", op);
Barry Warsaw7ce36942001-08-24 18:34:26 +000082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 return PyUnicode_FromFormat("<cell at %p: %.80s object at %p>",
84 op, op->ob_ref->ob_type->tp_name,
85 op->ob_ref);
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000086}
87
88static int
89cell_traverse(PyCellObject *op, visitproc visit, void *arg)
90{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 Py_VISIT(op->ob_ref);
92 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +000093}
94
95static int
96cell_clear(PyCellObject *op)
97{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 Py_CLEAR(op->ob_ref);
99 return 0;
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +0000100}
101
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000102static PyObject *
103cell_get_contents(PyCellObject *op, void *closure)
104{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 if (op->ob_ref == NULL)
106 {
107 PyErr_SetString(PyExc_ValueError, "Cell is empty");
108 return NULL;
109 }
110 Py_INCREF(op->ob_ref);
111 return op->ob_ref;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000112}
113
Victor Stinner0ad05c32017-09-20 06:54:13 -0700114static int
Lisa Roach64505a12017-06-08 04:43:26 -0700115cell_set_contents(PyCellObject *op, PyObject *obj)
116{
117 Py_XINCREF(obj);
118 Py_XSETREF(op->ob_ref, obj);
119 return 0;
120}
121
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000122static PyGetSetDef cell_getsetlist[] = {
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +0300123 {"cell_contents", (getter)cell_get_contents,
Lisa Roach64505a12017-06-08 04:43:26 -0700124 (setter)cell_set_contents, NULL},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 {NULL} /* sentinel */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000126};
127
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +0000128PyTypeObject PyCell_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 PyVarObject_HEAD_INIT(&PyType_Type, 0)
130 "cell",
131 sizeof(PyCellObject),
132 0,
Benjamin Peterson07451dd2016-05-12 23:12:21 -0700133 (destructor)cell_dealloc, /* tp_dealloc */
134 0, /* tp_print */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 0, /* tp_getattr */
136 0, /* tp_setattr */
137 0, /* tp_reserved */
138 (reprfunc)cell_repr, /* tp_repr */
139 0, /* tp_as_number */
140 0, /* tp_as_sequence */
141 0, /* tp_as_mapping */
142 0, /* tp_hash */
143 0, /* tp_call */
144 0, /* tp_str */
145 PyObject_GenericGetAttr, /* tp_getattro */
146 0, /* tp_setattro */
147 0, /* tp_as_buffer */
Benjamin Peterson07451dd2016-05-12 23:12:21 -0700148 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 0, /* tp_doc */
150 (traverseproc)cell_traverse, /* tp_traverse */
151 (inquiry)cell_clear, /* tp_clear */
152 cell_richcompare, /* tp_richcompare */
153 0, /* tp_weaklistoffset */
154 0, /* tp_iter */
155 0, /* tp_iternext */
156 0, /* tp_methods */
157 0, /* tp_members */
158 cell_getsetlist, /* tp_getset */
Jeremy Hyltonfbd849f2001-01-25 20:04:14 +0000159};