Coverage Report

Created: 2025-07-11 06:59

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