Coverage Report

Created: 2022-07-08 09:39

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