ยปCore Development>Code coverage>Objects/iterobject.c

Python code coverage for Objects/iterobject.c

#countcontent
1n/a/* Iterator objects */
2n/a
3n/a#include "Python.h"
4n/a
5n/atypedef struct {
6n/a PyObject_HEAD
7n/a Py_ssize_t it_index;
8n/a PyObject *it_seq; /* Set to NULL when iterator is exhausted */
9n/a} seqiterobject;
10n/a
11n/aPyObject *
12n/aPySeqIter_New(PyObject *seq)
13n/a{
14n/a seqiterobject *it;
15n/a
16n/a if (!PySequence_Check(seq)) {
17n/a PyErr_BadInternalCall();
18n/a return NULL;
19n/a }
20n/a it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
21n/a if (it == NULL)
22n/a return NULL;
23n/a it->it_index = 0;
24n/a Py_INCREF(seq);
25n/a it->it_seq = seq;
26n/a _PyObject_GC_TRACK(it);
27n/a return (PyObject *)it;
28n/a}
29n/a
30n/astatic void
31n/aiter_dealloc(seqiterobject *it)
32n/a{
33n/a _PyObject_GC_UNTRACK(it);
34n/a Py_XDECREF(it->it_seq);
35n/a PyObject_GC_Del(it);
36n/a}
37n/a
38n/astatic int
39n/aiter_traverse(seqiterobject *it, visitproc visit, void *arg)
40n/a{
41n/a Py_VISIT(it->it_seq);
42n/a return 0;
43n/a}
44n/a
45n/astatic PyObject *
46n/aiter_iternext(PyObject *iterator)
47n/a{
48n/a seqiterobject *it;
49n/a PyObject *seq;
50n/a PyObject *result;
51n/a
52n/a assert(PySeqIter_Check(iterator));
53n/a it = (seqiterobject *)iterator;
54n/a seq = it->it_seq;
55n/a if (seq == NULL)
56n/a return NULL;
57n/a if (it->it_index == PY_SSIZE_T_MAX) {
58n/a PyErr_SetString(PyExc_OverflowError,
59n/a "iter index too large");
60n/a return NULL;
61n/a }
62n/a
63n/a result = PySequence_GetItem(seq, it->it_index);
64n/a if (result != NULL) {
65n/a it->it_index++;
66n/a return result;
67n/a }
68n/a if (PyErr_ExceptionMatches(PyExc_IndexError) ||
69n/a PyErr_ExceptionMatches(PyExc_StopIteration))
70n/a {
71n/a PyErr_Clear();
72n/a it->it_seq = NULL;
73n/a Py_DECREF(seq);
74n/a }
75n/a return NULL;
76n/a}
77n/a
78n/astatic PyObject *
79n/aiter_len(seqiterobject *it)
80n/a{
81n/a Py_ssize_t seqsize, len;
82n/a
83n/a if (it->it_seq) {
84n/a if (_PyObject_HasLen(it->it_seq)) {
85n/a seqsize = PySequence_Size(it->it_seq);
86n/a if (seqsize == -1)
87n/a return NULL;
88n/a }
89n/a else {
90n/a Py_RETURN_NOTIMPLEMENTED;
91n/a }
92n/a len = seqsize - it->it_index;
93n/a if (len >= 0)
94n/a return PyLong_FromSsize_t(len);
95n/a }
96n/a return PyLong_FromLong(0);
97n/a}
98n/a
99n/aPyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
100n/a
101n/astatic PyObject *
102n/aiter_reduce(seqiterobject *it)
103n/a{
104n/a if (it->it_seq != NULL)
105n/a return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
106n/a it->it_seq, it->it_index);
107n/a else
108n/a return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
109n/a}
110n/a
111n/aPyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
112n/a
113n/astatic PyObject *
114n/aiter_setstate(seqiterobject *it, PyObject *state)
115n/a{
116n/a Py_ssize_t index = PyLong_AsSsize_t(state);
117n/a if (index == -1 && PyErr_Occurred())
118n/a return NULL;
119n/a if (it->it_seq != NULL) {
120n/a if (index < 0)
121n/a index = 0;
122n/a it->it_index = index;
123n/a }
124n/a Py_RETURN_NONE;
125n/a}
126n/a
127n/aPyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
128n/a
129n/astatic PyMethodDef seqiter_methods[] = {
130n/a {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
131n/a {"__reduce__", (PyCFunction)iter_reduce, METH_NOARGS, reduce_doc},
132n/a {"__setstate__", (PyCFunction)iter_setstate, METH_O, setstate_doc},
133n/a {NULL, NULL} /* sentinel */
134n/a};
135n/a
136n/aPyTypeObject PySeqIter_Type = {
137n/a PyVarObject_HEAD_INIT(&PyType_Type, 0)
138n/a "iterator", /* tp_name */
139n/a sizeof(seqiterobject), /* tp_basicsize */
140n/a 0, /* tp_itemsize */
141n/a /* methods */
142n/a (destructor)iter_dealloc, /* tp_dealloc */
143n/a 0, /* tp_print */
144n/a 0, /* tp_getattr */
145n/a 0, /* tp_setattr */
146n/a 0, /* tp_reserved */
147n/a 0, /* tp_repr */
148n/a 0, /* tp_as_number */
149n/a 0, /* tp_as_sequence */
150n/a 0, /* tp_as_mapping */
151n/a 0, /* tp_hash */
152n/a 0, /* tp_call */
153n/a 0, /* tp_str */
154n/a PyObject_GenericGetAttr, /* tp_getattro */
155n/a 0, /* tp_setattro */
156n/a 0, /* tp_as_buffer */
157n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
158n/a 0, /* tp_doc */
159n/a (traverseproc)iter_traverse, /* tp_traverse */
160n/a 0, /* tp_clear */
161n/a 0, /* tp_richcompare */
162n/a 0, /* tp_weaklistoffset */
163n/a PyObject_SelfIter, /* tp_iter */
164n/a iter_iternext, /* tp_iternext */
165n/a seqiter_methods, /* tp_methods */
166n/a 0, /* tp_members */
167n/a};
168n/a
169n/a/* -------------------------------------- */
170n/a
171n/atypedef struct {
172n/a PyObject_HEAD
173n/a PyObject *it_callable; /* Set to NULL when iterator is exhausted */
174n/a PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
175n/a} calliterobject;
176n/a
177n/aPyObject *
178n/aPyCallIter_New(PyObject *callable, PyObject *sentinel)
179n/a{
180n/a calliterobject *it;
181n/a it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
182n/a if (it == NULL)
183n/a return NULL;
184n/a Py_INCREF(callable);
185n/a it->it_callable = callable;
186n/a Py_INCREF(sentinel);
187n/a it->it_sentinel = sentinel;
188n/a _PyObject_GC_TRACK(it);
189n/a return (PyObject *)it;
190n/a}
191n/astatic void
192n/acalliter_dealloc(calliterobject *it)
193n/a{
194n/a _PyObject_GC_UNTRACK(it);
195n/a Py_XDECREF(it->it_callable);
196n/a Py_XDECREF(it->it_sentinel);
197n/a PyObject_GC_Del(it);
198n/a}
199n/a
200n/astatic int
201n/acalliter_traverse(calliterobject *it, visitproc visit, void *arg)
202n/a{
203n/a Py_VISIT(it->it_callable);
204n/a Py_VISIT(it->it_sentinel);
205n/a return 0;
206n/a}
207n/a
208n/astatic PyObject *
209n/acalliter_iternext(calliterobject *it)
210n/a{
211n/a PyObject *result;
212n/a
213n/a if (it->it_callable == NULL) {
214n/a return NULL;
215n/a }
216n/a
217n/a result = _PyObject_CallNoArg(it->it_callable);
218n/a if (result != NULL) {
219n/a int ok;
220n/a
221n/a ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ);
222n/a if (ok == 0) {
223n/a return result; /* Common case, fast path */
224n/a }
225n/a
226n/a Py_DECREF(result);
227n/a if (ok > 0) {
228n/a Py_CLEAR(it->it_callable);
229n/a Py_CLEAR(it->it_sentinel);
230n/a }
231n/a }
232n/a else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
233n/a PyErr_Clear();
234n/a Py_CLEAR(it->it_callable);
235n/a Py_CLEAR(it->it_sentinel);
236n/a }
237n/a return NULL;
238n/a}
239n/a
240n/astatic PyObject *
241n/acalliter_reduce(calliterobject *it)
242n/a{
243n/a if (it->it_callable != NULL && it->it_sentinel != NULL)
244n/a return Py_BuildValue("N(OO)", _PyObject_GetBuiltin("iter"),
245n/a it->it_callable, it->it_sentinel);
246n/a else
247n/a return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
248n/a}
249n/a
250n/astatic PyMethodDef calliter_methods[] = {
251n/a {"__reduce__", (PyCFunction)calliter_reduce, METH_NOARGS, reduce_doc},
252n/a {NULL, NULL} /* sentinel */
253n/a};
254n/a
255n/aPyTypeObject PyCallIter_Type = {
256n/a PyVarObject_HEAD_INIT(&PyType_Type, 0)
257n/a "callable_iterator", /* tp_name */
258n/a sizeof(calliterobject), /* tp_basicsize */
259n/a 0, /* tp_itemsize */
260n/a /* methods */
261n/a (destructor)calliter_dealloc, /* tp_dealloc */
262n/a 0, /* tp_print */
263n/a 0, /* tp_getattr */
264n/a 0, /* tp_setattr */
265n/a 0, /* tp_reserved */
266n/a 0, /* tp_repr */
267n/a 0, /* tp_as_number */
268n/a 0, /* tp_as_sequence */
269n/a 0, /* tp_as_mapping */
270n/a 0, /* tp_hash */
271n/a 0, /* tp_call */
272n/a 0, /* tp_str */
273n/a PyObject_GenericGetAttr, /* tp_getattro */
274n/a 0, /* tp_setattro */
275n/a 0, /* tp_as_buffer */
276n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
277n/a 0, /* tp_doc */
278n/a (traverseproc)calliter_traverse, /* tp_traverse */
279n/a 0, /* tp_clear */
280n/a 0, /* tp_richcompare */
281n/a 0, /* tp_weaklistoffset */
282n/a PyObject_SelfIter, /* tp_iter */
283n/a (iternextfunc)calliter_iternext, /* tp_iternext */
284n/a calliter_methods, /* tp_methods */
285n/a};
286n/a
287n/a