Changeset 388 for python/vendor/current/Objects/iterobject.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Objects/iterobject.c
r2 r388 4 4 5 5 typedef struct { 6 7 8 6 PyObject_HEAD 7 long it_index; 8 PyObject *it_seq; /* Set to NULL when iterator is exhausted */ 9 9 } seqiterobject; 10 10 … … 12 12 PySeqIter_New(PyObject *seq) 13 13 { 14 15 16 17 18 19 } 20 21 22 23 24 25 26 27 14 seqiterobject *it; 15 16 if (!PySequence_Check(seq)) { 17 PyErr_BadInternalCall(); 18 return NULL; 19 } 20 it = PyObject_GC_New(seqiterobject, &PySeqIter_Type); 21 if (it == NULL) 22 return NULL; 23 it->it_index = 0; 24 Py_INCREF(seq); 25 it->it_seq = seq; 26 _PyObject_GC_TRACK(it); 27 return (PyObject *)it; 28 28 } 29 29 … … 31 31 iter_dealloc(seqiterobject *it) 32 32 { 33 34 35 33 _PyObject_GC_UNTRACK(it); 34 Py_XDECREF(it->it_seq); 35 PyObject_GC_Del(it); 36 36 } 37 37 … … 39 39 iter_traverse(seqiterobject *it, visitproc visit, void *arg) 40 40 { 41 42 41 Py_VISIT(it->it_seq); 42 return 0; 43 43 } 44 44 … … 46 46 iter_iternext(PyObject *iterator) 47 47 { 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 48 seqiterobject *it; 49 PyObject *seq; 50 PyObject *result; 51 52 assert(PySeqIter_Check(iterator)); 53 it = (seqiterobject *)iterator; 54 seq = it->it_seq; 55 if (seq == NULL) 56 return NULL; 57 58 result = PySequence_GetItem(seq, it->it_index); 59 if (result != NULL) { 60 it->it_index++; 61 return result; 62 } 63 if (PyErr_ExceptionMatches(PyExc_IndexError) || 64 PyErr_ExceptionMatches(PyExc_StopIteration)) 65 { 66 PyErr_Clear(); 67 Py_DECREF(seq); 68 it->it_seq = NULL; 69 } 70 return NULL; 71 71 } 72 72 … … 74 74 iter_len(seqiterobject *it) 75 75 { 76 77 78 79 80 81 82 83 84 85 86 76 Py_ssize_t seqsize, len; 77 78 if (it->it_seq) { 79 seqsize = PySequence_Size(it->it_seq); 80 if (seqsize == -1) 81 return NULL; 82 len = seqsize - it->it_index; 83 if (len >= 0) 84 return PyInt_FromSsize_t(len); 85 } 86 return PyInt_FromLong(0); 87 87 } 88 88 … … 90 90 91 91 static PyMethodDef seqiter_methods[] = { 92 93 {NULL, NULL}/* sentinel */92 {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc}, 93 {NULL, NULL} /* sentinel */ 94 94 }; 95 95 96 96 PyTypeObject PySeqIter_Type = { 97 98 "iterator",/* tp_name */99 sizeof(seqiterobject),/* tp_basicsize */100 0,/* tp_itemsize */101 102 (destructor)iter_dealloc,/* tp_dealloc */103 0,/* tp_print */104 0,/* tp_getattr */105 0,/* tp_setattr */106 0,/* tp_compare */107 0,/* tp_repr */108 0,/* tp_as_number */109 0,/* tp_as_sequence */110 0,/* tp_as_mapping */111 0,/* tp_hash */112 0,/* tp_call */113 0,/* tp_str */114 PyObject_GenericGetAttr,/* tp_getattro */115 0,/* tp_setattro */116 0,/* tp_as_buffer */117 118 0,/* tp_doc */119 (traverseproc)iter_traverse,/* tp_traverse */120 0,/* tp_clear */121 0,/* tp_richcompare */122 0,/* tp_weaklistoffset */123 PyObject_SelfIter,/* tp_iter */124 iter_iternext,/* tp_iternext */125 seqiter_methods,/* tp_methods */126 0,/* tp_members */97 PyVarObject_HEAD_INIT(&PyType_Type, 0) 98 "iterator", /* tp_name */ 99 sizeof(seqiterobject), /* tp_basicsize */ 100 0, /* tp_itemsize */ 101 /* methods */ 102 (destructor)iter_dealloc, /* tp_dealloc */ 103 0, /* tp_print */ 104 0, /* tp_getattr */ 105 0, /* tp_setattr */ 106 0, /* tp_compare */ 107 0, /* tp_repr */ 108 0, /* tp_as_number */ 109 0, /* tp_as_sequence */ 110 0, /* tp_as_mapping */ 111 0, /* tp_hash */ 112 0, /* tp_call */ 113 0, /* tp_str */ 114 PyObject_GenericGetAttr, /* tp_getattro */ 115 0, /* tp_setattro */ 116 0, /* tp_as_buffer */ 117 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 118 0, /* tp_doc */ 119 (traverseproc)iter_traverse, /* tp_traverse */ 120 0, /* tp_clear */ 121 0, /* tp_richcompare */ 122 0, /* tp_weaklistoffset */ 123 PyObject_SelfIter, /* tp_iter */ 124 iter_iternext, /* tp_iternext */ 125 seqiter_methods, /* tp_methods */ 126 0, /* tp_members */ 127 127 }; 128 128 … … 130 130 131 131 typedef struct { 132 133 134 132 PyObject_HEAD 133 PyObject *it_callable; /* Set to NULL when iterator is exhausted */ 134 PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */ 135 135 } calliterobject; 136 136 … … 138 138 PyCallIter_New(PyObject *callable, PyObject *sentinel) 139 139 { 140 141 142 143 144 145 146 147 148 149 140 calliterobject *it; 141 it = PyObject_GC_New(calliterobject, &PyCallIter_Type); 142 if (it == NULL) 143 return NULL; 144 Py_INCREF(callable); 145 it->it_callable = callable; 146 Py_INCREF(sentinel); 147 it->it_sentinel = sentinel; 148 _PyObject_GC_TRACK(it); 149 return (PyObject *)it; 150 150 } 151 151 static void 152 152 calliter_dealloc(calliterobject *it) 153 153 { 154 155 156 157 154 _PyObject_GC_UNTRACK(it); 155 Py_XDECREF(it->it_callable); 156 Py_XDECREF(it->it_sentinel); 157 PyObject_GC_Del(it); 158 158 } 159 159 … … 161 161 calliter_traverse(calliterobject *it, visitproc visit, void *arg) 162 162 { 163 164 165 163 Py_VISIT(it->it_callable); 164 Py_VISIT(it->it_sentinel); 165 return 0; 166 166 } 167 167 … … 169 169 calliter_iternext(calliterobject *it) 170 170 { 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 171 if (it->it_callable != NULL) { 172 PyObject *args = PyTuple_New(0); 173 PyObject *result; 174 if (args == NULL) 175 return NULL; 176 result = PyObject_Call(it->it_callable, args, NULL); 177 Py_DECREF(args); 178 if (result != NULL) { 179 int ok; 180 ok = PyObject_RichCompareBool(result, 181 it->it_sentinel, 182 Py_EQ); 183 if (ok == 0) 184 return result; /* Common case, fast path */ 185 Py_DECREF(result); 186 if (ok > 0) { 187 Py_CLEAR(it->it_callable); 188 Py_CLEAR(it->it_sentinel); 189 } 190 } 191 else if (PyErr_ExceptionMatches(PyExc_StopIteration)) { 192 PyErr_Clear(); 193 Py_CLEAR(it->it_callable); 194 Py_CLEAR(it->it_sentinel); 195 } 196 } 197 return NULL; 198 198 } 199 199 200 200 PyTypeObject PyCallIter_Type = { 201 202 "callable-iterator",/* tp_name */203 sizeof(calliterobject),/* tp_basicsize */204 0,/* tp_itemsize */205 206 (destructor)calliter_dealloc,/* tp_dealloc */207 0,/* tp_print */208 0,/* tp_getattr */209 0,/* tp_setattr */210 0,/* tp_compare */211 0,/* tp_repr */212 0,/* tp_as_number */213 0,/* tp_as_sequence */214 0,/* tp_as_mapping */215 0,/* tp_hash */216 0,/* tp_call */217 0,/* tp_str */218 PyObject_GenericGetAttr,/* tp_getattro */219 0,/* tp_setattro */220 0,/* tp_as_buffer */221 222 0,/* tp_doc */223 (traverseproc)calliter_traverse,/* tp_traverse */224 0,/* tp_clear */225 0,/* tp_richcompare */226 0,/* tp_weaklistoffset */227 PyObject_SelfIter,/* tp_iter */228 (iternextfunc)calliter_iternext,/* tp_iternext */229 0,/* tp_methods */201 PyVarObject_HEAD_INIT(&PyType_Type, 0) 202 "callable-iterator", /* tp_name */ 203 sizeof(calliterobject), /* tp_basicsize */ 204 0, /* tp_itemsize */ 205 /* methods */ 206 (destructor)calliter_dealloc, /* tp_dealloc */ 207 0, /* tp_print */ 208 0, /* tp_getattr */ 209 0, /* tp_setattr */ 210 0, /* tp_compare */ 211 0, /* tp_repr */ 212 0, /* tp_as_number */ 213 0, /* tp_as_sequence */ 214 0, /* tp_as_mapping */ 215 0, /* tp_hash */ 216 0, /* tp_call */ 217 0, /* tp_str */ 218 PyObject_GenericGetAttr, /* tp_getattro */ 219 0, /* tp_setattro */ 220 0, /* tp_as_buffer */ 221 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 222 0, /* tp_doc */ 223 (traverseproc)calliter_traverse, /* tp_traverse */ 224 0, /* tp_clear */ 225 0, /* tp_richcompare */ 226 0, /* tp_weaklistoffset */ 227 PyObject_SelfIter, /* tp_iter */ 228 (iternextfunc)calliter_iternext, /* tp_iternext */ 229 0, /* tp_methods */ 230 230 };
Note:
See TracChangeset
for help on using the changeset viewer.