Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(59)

Side by Side Diff: Objects/rangeobject.c

Issue 602: range: lean and mean (Closed) SVN Base: http://svn.python.org/view/*checkout*/python/branches/py3k/
Patch Set: __len__ is back! Created 3 months, 3 weeks ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* Range object implementation */ 1 /* Range object implementation */
2 2
3 #include "Python.h" 3 #include "Python.h"
4 #include "structmember.h"
4 5
5 /* Support objects whose length is > PY_SSIZE_T_MAX. 6 /* Support objects whose length is > PY_SSIZE_T_MAX.
6 7
7 This could be sped up for small PyLongs if they fit in an Py_ssize_t. 8 This could be sped up for small PyLongs if they fit in an Py_ssize_t.
8 This only matters on Win64. Though we could use PY_LONG_LONG which 9 This only matters on Win64. Though we could use PY_LONG_LONG which
9 would presumably help perf. 10 would presumably help perf.
10 */ 11 */
11 12
12 typedef struct { 13 typedef struct {
13 PyObject_HEAD 14 PyObject_HEAD
14 PyObject *start; 15 PyObject *start;
15 PyObject *stop; 16 PyObject *stop;
16 PyObject *step; 17 PyObject *step;
18 PyObject *length;
17 } rangeobject; 19 } rangeobject;
18 20
19 /* Helper function for validating step. Always returns a new reference or 21 /* Helper function for validating step. Always returns a new reference or
20 NULL on error. 22 NULL on error.
21 */ 23 */
22 static PyObject * 24 static PyObject *
23 validate_step(PyObject *step) 25 validate_step(PyObject *step)
24 { 26 {
25 /* No step specified, use a step of 1. */ 27 /* No step specified, use a step of 1. */
26 if (!step) 28 if (!step)
27 return PyLong_FromLong(1); 29 return PyLong_FromLong(1);
28 30
29 step = PyNumber_Index(step); 31 step = PyNumber_Index(step);
30 if (step) { 32 if (step) {
31 Py_ssize_t istep = PyNumber_AsSsize_t(step, NULL); 33 Py_ssize_t istep = PyNumber_AsSsize_t(step, NULL);
32 if (istep == -1 && PyErr_Occurred()) { 34 if (istep == -1 && PyErr_Occurred()) {
33 /* Ignore OverflowError, we know the value isn't 0. */ 35 /* Ignore OverflowError, we know the value isn't 0. */
34 PyErr_Clear(); 36 PyErr_Clear();
35 } 37 }
36 else if (istep == 0) { 38 else if (istep == 0) {
37 PyErr_SetString(PyExc_ValueError, 39 PyErr_SetString(PyExc_ValueError,
38 "range() arg 3 must not be zero"); 40 "range() arg 3 must not be zero");
39 Py_CLEAR(step); 41 Py_CLEAR(step);
40 } 42 }
41 } 43 }
42 44
43 return step; 45 return step;
44 } 46 }
47
48 static PyObject* range_compute_length(PyObject *start,
49 PyObject *stop, PyObject *step);
45 50
46 /* XXX(nnorwitz): should we error check if the user passes any empty ranges? 51 /* XXX(nnorwitz): should we error check if the user passes any empty ranges?
47 range(-10) 52 range(-10)
48 range(0, -5) 53 range(0, -5)
49 range(0, 5, -1) 54 range(0, 5, -1)
50 */ 55 */
51 static PyObject * 56 static PyObject *
52 range_new(PyTypeObject *type, PyObject *args, PyObject *kw) 57 range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
53 { 58 {
54 rangeobject *obj = NULL; 59 rangeobject *obj = NULL;
55 PyObject *start = NULL, *stop = NULL, *step = NULL; 60 PyObject *start = NULL, *stop = NULL, *step = NULL, *length = NULL;
56 61
57 if (!_PyArg_NoKeywords("range()", kw)) 62 if (!_PyArg_NoKeywords("range()", kw))
58 return NULL; 63 return NULL;
59 64
60 if (PyTuple_Size(args) <= 1) { 65 if (PyTuple_Size(args) <= 1) {
61 if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop)) 66 if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
62 goto Fail; 67 goto Fail;
63 stop = PyNumber_Index(stop); 68 stop = PyNumber_Index(stop);
64 if (!stop) 69 if (!stop)
65 goto Fail; 70 goto Fail;
66 start = PyLong_FromLong(0); 71 start = PyLong_FromLong(0);
67 step = PyLong_FromLong(1); 72 step = PyLong_FromLong(1);
68 if (!start || !step) 73 if (!start || !step)
69 goto Fail; 74 goto Fail;
70 } 75 }
71 else { 76 else {
72 if (!PyArg_UnpackTuple(args, "range", 2, 3, 77 if (!PyArg_UnpackTuple(args, "range", 2, 3,
73 &start, &stop, &step)) 78 &start, &stop, &step))
74 goto Fail; 79 goto Fail;
75 80
76 /* Convert borrowed refs to owned refs */ 81 /* Convert borrowed refs to owned refs */
77 start = PyNumber_Index(start); 82 start = PyNumber_Index(start);
78 stop = PyNumber_Index(stop); 83 stop = PyNumber_Index(stop);
79 step = validate_step(step); 84 step = validate_step(step);
80 if (!start || !stop || !step) 85 if (!start || !stop || !step)
81 goto Fail; 86 goto Fail;
82 } 87 }
83 88
89 length = range_compute_length(start, stop, step);
90 if (length == NULL)
91 goto Fail;
84 obj = PyObject_New(rangeobject, &PyRange_Type); 92 obj = PyObject_New(rangeobject, &PyRange_Type);
85 if (obj == NULL) 93 if (obj == NULL)
86 goto Fail; 94 goto Fail;
87 obj->start = start; 95 obj->start = start;
88 obj->stop = stop; 96 obj->stop = stop;
89 obj->step = step; 97 obj->step = step;
98 obj->length = length;
90 return (PyObject *) obj; 99 return (PyObject *) obj;
91 100
92 Fail: 101 Fail:
93 Py_XDECREF(start); 102 Py_XDECREF(start);
94 Py_XDECREF(stop); 103 Py_XDECREF(stop);
95 Py_XDECREF(step); 104 Py_XDECREF(step);
105 Py_XDECREF(length);
96 return NULL; 106 return NULL;
97 } 107 }
98 108
99 PyDoc_STRVAR(range_doc, 109 PyDoc_STRVAR(range_doc,
100 "range([start,] stop[, step]) -> range object\n\ 110 "range([start,] stop[, step]) -> range object\n\
101 \n\ 111 \n\
102 Returns an iterator that generates the numbers in the range on demand."); 112 Return an arithmetic progression of numbers from start "
113 "to stop (exclusive) by step.");
103 114
104 static void 115 static void
105 range_dealloc(rangeobject *r) 116 range_dealloc(rangeobject *r)
106 { 117 {
107 Py_DECREF(r->start); 118 Py_DECREF(r->start);
108 Py_DECREF(r->stop); 119 Py_DECREF(r->stop);
109 Py_DECREF(r->step); 120 Py_DECREF(r->step);
121 Py_DECREF(r->length);
110 PyObject_Del(r); 122 PyObject_Del(r);
111 } 123 }
112 124
113 /* Return number of items in range (lo, hi, step), when arguments are 125 static PyObject *
114 * PyInt or PyLong objects. step > 0 required. Return a value < 0 if 126 range_compute_length(PyObject *start, PyObject *stop, PyObject *step)
115 * & only if the true value is too large to fit in a signed long.
116 * Arguments MUST return 1 with either PyLong_Check() or
117 * PyLong_Check(). Return -1 when there is an error.
118 */
119 static PyObject*
120 range_length_obj(rangeobject *r)
121 { 127 {
122 /* ------------------------------------------------------------- 128 /* -------------------------------------------------------------
123 Algorithm is equal to that of get_len_of_range(), but it operates 129 Algorithm is equal to that of get_len_of_range(), but it operates
124 on PyObjects (which are assumed to be PyLong or PyInt objects). 130 on PyObjects (which are assumed to be PyLong or PyInt objects).
125 ---------------------------------------------------------------*/ 131 ---------------------------------------------------------------*/
126 int cmp_result, cmp_call; 132 int cmp_result, cmp_call;
127 PyObject *lo, *hi; 133 PyObject *lo, *hi;
128 PyObject *step = NULL;
129 PyObject *diff = NULL; 134 PyObject *diff = NULL;
130 PyObject *one = NULL; 135 PyObject *one = NULL;
131 PyObject *tmp1 = NULL, *tmp2 = NULL, *result; 136 PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
132 /* holds sub-expression evaluations */ 137 /* holds sub-expression evaluations */
133 138
134 PyObject *zero = PyLong_FromLong(0); 139 PyObject *zero = PyLong_FromLong(0);
135 if (zero == NULL) 140 if (zero == NULL)
136 return NULL; 141 return NULL;
137 cmp_call = PyObject_Cmp(r->step, zero, &cmp_result); 142 cmp_call = PyObject_Cmp(step, zero, &cmp_result);
138 Py_DECREF(zero); 143 Py_DECREF(zero);
139 if (cmp_call == -1) 144 if (cmp_call == -1)
140 return NULL; 145 return NULL;
141 146
142 assert(cmp_result != 0); 147 assert(cmp_result != 0);
143 if (cmp_result > 0) { 148 if (cmp_result > 0) {
144 lo = r->start; 149 lo = start;
145 hi = r->stop; 150 hi = stop;
146 step = r->step;
147 Py_INCREF(step); 151 Py_INCREF(step);
148 } else { 152 } else {
149 lo = r->stop; 153 lo = stop;
150 hi = r->start; 154 hi = start;
151 step = PyNumber_Negative(r->step); 155 step = PyNumber_Negative(step);
152 if (!step) 156 if (!step)
153 return NULL; 157 goto Fail;
154 } 158 }
155 159
156 /* if (lo >= hi), return length of 0. */ 160 /* if (lo >= hi), return length of 0. */
157 if (PyObject_Compare(lo, hi) >= 0) { 161 if (PyObject_Compare(lo, hi) >= 0) {
158 Py_XDECREF(step); 162 Py_XDECREF(step);
159 return PyLong_FromLong(0); 163 return PyLong_FromLong(0);
160 } 164 }
161 165
162 if ((one = PyLong_FromLong(1L)) == NULL) 166 if ((one = PyLong_FromLong(1L)) == NULL)
163 goto Fail; 167 goto Fail;
164 168
165 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) 169 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
166 goto Fail; 170 goto Fail;
167 171
168 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL) 172 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
169 goto Fail; 173 goto Fail;
170 174
171 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL) 175 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
172 goto Fail; 176 goto Fail;
173 177
174 if ((result = PyNumber_Add(tmp2, one)) == NULL) 178 if ((result = PyNumber_Add(tmp2, one)) == NULL)
175 goto Fail; 179 goto Fail;
176 180
177 Py_DECREF(tmp2); 181 Py_DECREF(tmp2);
178 Py_DECREF(diff); 182 Py_DECREF(diff);
179 Py_DECREF(step); 183 Py_DECREF(step);
180 Py_DECREF(tmp1); 184 Py_DECREF(tmp1);
181 Py_DECREF(one); 185 Py_DECREF(one);
182 return result; 186 return result;
183 187
184 Fail: 188 Fail:
185 Py_XDECREF(tmp2); 189 Py_XDECREF(tmp2);
186 Py_XDECREF(diff); 190 Py_XDECREF(diff);
187 Py_XDECREF(step); 191 Py_XDECREF(step);
188 Py_XDECREF(tmp1); 192 Py_XDECREF(tmp1);
189 Py_XDECREF(one); 193 Py_XDECREF(one);
190 return NULL; 194 return NULL;
191 } 195 }
192 196
193 static Py_ssize_t 197 static Py_ssize_t
194 range_length(rangeobject *r) 198 range_length(rangeobject *r)
195 { 199 {
196 PyObject *len = range_length_obj(r); 200 return PyLong_AsSsize_t(r->length);
197 Py_ssize_t result = -1;
198 if (len) {
199 result = PyLong_AsSsize_t(len);
200 Py_DECREF(len);
201 }
202 return result;
203 } 201 }
204 202
205 /* range(...)[x] is necessary for: seq[:] = range(...) */
206
207 static PyObject *
208 range_item(rangeobject *r, Py_ssize_t i)
209 {
210 Py_ssize_t len = range_length(r);
211 PyObject *rem, *incr, *result;
212
213 /* XXX(nnorwitz): should negative indices be supported? */
214 /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */
215 if (i < 0 || i >= len) {
216 if (!PyErr_Occurred())
217 PyErr_SetString(PyExc_IndexError,
218 "range object index out of range");
219 return NULL;
220 }
221
222 /* XXX(nnorwitz): optimize for short ints. */
223 rem = PyLong_FromSsize_t(i);
224 if (!rem)
225 return NULL;
226 incr = PyNumber_Multiply(rem, r->step);
227 Py_DECREF(rem);
228 if (!incr)
229 return NULL;
230 result = PyNumber_Add(r->start, incr);
231 Py_DECREF(incr);
232 return result;
233 }
234 203
235 static PyObject * 204 static PyObject *
236 range_repr(rangeobject *r) 205 range_repr(rangeobject *r)
237 { 206 {
238 Py_ssize_t istep; 207 Py_ssize_t istep;
239 208
240 /* Check for special case values for printing. We don't always 209 /* Check for special case values for printing. We don't always
241 need the step value. We don't care about errors 210 need the step value. We don't care about errors
242 (it means overflow), so clear the errors. */ 211 (it means overflow), so clear the errors. */
243 istep = PyNumber_AsSsize_t(r->step, NULL); 212 istep = PyNumber_AsSsize_t(r->step, NULL);
244 if (istep != 1 || (istep == -1 && PyErr_Occurred())) { 213 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
245 PyErr_Clear(); 214 PyErr_Clear();
246 } 215 }
247 216
248 if (istep == 1) 217 if (istep == 1)
249 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop); 218 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
250 else 219 else
251 return PyUnicode_FromFormat("range(%R, %R, %R)", 220 return PyUnicode_FromFormat("range(%R, %R, %R)",
252 r->start, r->stop, r->step); 221 r->start, r->stop, r->step);
253 } 222 }
254 223
255 static PySequenceMethods range_as_sequence = { 224 static PyMemberDef range_members[] = {
256 (lenfunc)range_length, /* sq_length */ 225 {"start", T_OBJECT, offsetof(rangeobject, start), READONLY},
257 0, /* sq_concat */ 226 {"stop", T_OBJECT, offsetof(rangeobject, stop), READONLY},
258 0, /* sq_repeat */ 227 {"step", T_OBJECT, offsetof(rangeobject, step), READONLY},
259 (ssizeargfunc)range_item, /* sq_item */ 228 {0}
260 0, /* sq_slice */
261 }; 229 };
262 230
263 static PyObject * range_iter(PyObject *seq); 231 static PyObject * range_iter(PyObject *seq);
264 static PyObject * range_reverse(PyObject *seq); 232 static PyObject * range_reverse(PyObject *seq);
265 233
266 PyDoc_STRVAR(reverse_doc, 234 PyDoc_STRVAR(reverse_doc,
267 "Returns a reverse iterator."); 235 "Returns a reverse iterator.");
236
237 static PySequenceMethods range_as_sequence = {
238 (lenfunc)range_length, /* sq_length */
239 0, /* sq_concat */
240 0, /* sq_repeat */
241 0, /* sq_item */
242 0, /* sq_slice */
243 0, /* sq_ass_item */
244 0, /* sq_ass_slice */
245 0, /* sq_contains */
246 0, /* sq_inplace_concat */
247 0, /* sq_inplace_repeat */
248 };
268 249
269 static PyMethodDef range_methods[] = { 250 static PyMethodDef range_methods[] = {
270 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, 251 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
271 reverse_doc}, 252 reverse_doc},
272 {NULL, NULL} /* sentinel */ 253 {NULL, NULL} /* sentinel */
273 }; 254 };
274 255
275 PyTypeObject PyRange_Type = { 256 PyTypeObject PyRange_Type = {
276 PyVarObject_HEAD_INIT(&PyType_Type, 0) 257 PyVarObject_HEAD_INIT(&PyType_Type, 0)
277 "range", /* Name of this type */ 258 "range", /* Name of this type */
278 sizeof(rangeobject), /* Basic object size */ 259 sizeof(rangeobject), /* Basic object size */
279 0, /* Item size for varobject */ 260 0, /* Item size for varobject */
280 (destructor)range_dealloc, /* tp_dealloc */ 261 (destructor)range_dealloc, /* tp_dealloc */
281 0, /* tp_print */ 262 0, /* tp_print */
282 0, /* tp_getattr */ 263 0, /* tp_getattr */
283 0, /* tp_setattr */ 264 0, /* tp_setattr */
284 0, /* tp_compare */ 265 0, /* tp_compare */
285 (reprfunc)range_repr, /* tp_repr */ 266 (reprfunc)range_repr, /* tp_repr */
286 0, /* tp_as_number */ 267 0, /* tp_as_number */
287 &range_as_sequence, /* tp_as_sequence */ 268 &range_as_sequence, /* tp_as_sequence */
288 0, /* tp_as_mapping */ 269 0, /* tp_as_mapping */
289 0, /* tp_hash */ 270 0, /* tp_hash */
290 0, /* tp_call */ 271 0, /* tp_call */
291 0, /* tp_str */ 272 0, /* tp_str */
292 PyObject_GenericGetAttr, /* tp_getattro */ 273 PyObject_GenericGetAttr, /* tp_getattro */
293 0, /* tp_setattro */ 274 0, /* tp_setattro */
294 0, /* tp_as_buffer */ 275 0, /* tp_as_buffer */
295 Py_TPFLAGS_DEFAULT, /* tp_flags */ 276 Py_TPFLAGS_DEFAULT, /* tp_flags */
296 range_doc, /* tp_doc */ 277 range_doc, /* tp_doc */
297 0, /* tp_traverse */ 278 0, /* tp_traverse */
298 0, /* tp_clear */ 279 0, /* tp_clear */
299 0, /* tp_richcompare */ 280 0, /* tp_richcompare */
300 0, /* tp_weaklistoffset */ 281 0, /* tp_weaklistoffset */
301 range_iter, /* tp_iter */ 282 range_iter, /* tp_iter */
302 0, /* tp_iternext */ 283 0, /* tp_iternext */
303 range_methods, /* tp_methods */ 284 range_methods, /* tp_methods */
304 0, /* tp_members */ 285 range_members, /* tp_members */
305 0, /* tp_getset */ 286 0, /* tp_getset */
306 0, /* tp_base */ 287 0, /* tp_base */
307 0, /* tp_dict */ 288 0, /* tp_dict */
308 0, /* tp_descr_get */ 289 0, /* tp_descr_get */
309 0, /* tp_descr_set */ 290 0, /* tp_descr_set */
310 0, /* tp_dictoffset */ 291 0, /* tp_dictoffset */
311 0, /* tp_init */ 292 0, /* tp_init */
312 0, /* tp_alloc */ 293 0, /* tp_alloc */
313 range_new, /* tp_new */ 294 range_new, /* tp_new */
314 }; 295 };
315 296
316 /*********************** range Iterator **************************/ 297 /*********************** range Iterator **************************/
317 298
318 /* There are 2 types of iterators, one for C longs, the other for 299 /* There are 2 types of iterators, one for C longs, the other for
319 Python longs (ie, PyObjects). This should make iteration fast 300 Python longs (ie, PyObjects). This should make iteration fast
320 in the normal case, but possible for any numeric value. 301 in the normal case, but possible for any numeric value.
321 */ 302 */
322 303
323 typedef struct { 304 typedef struct {
324 PyObject_HEAD 305 PyObject_HEAD
325 long index; 306 long index;
326 long start; 307 long start;
327 long step; 308 long step;
328 long len; 309 long len;
329 } rangeiterobject; 310 } rangeiterobject;
330 311
331 static PyObject * 312 static PyObject *
332 rangeiter_next(rangeiterobject *r) 313 rangeiter_next(rangeiterobject *r)
333 { 314 {
334 if (r->index < r->len) 315 if (r->index < r->len)
335 return PyLong_FromLong(r->start + (r->index++) * r->step); 316 return PyLong_FromLong(r->start + (r->index++) * r->step);
336 return NULL; 317 return NULL;
337 } 318 }
338 319
339 static PyObject * 320 static PyObject *
340 rangeiter_len(rangeiterobject *r) 321 rangeiter_len(rangeiterobject *r)
341 { 322 {
342 return PyLong_FromLong(r->len - r->index); 323 return PyLong_FromLong(r->len - r->index);
343 } 324 }
344 325
345 typedef struct { 326 typedef struct {
346 PyObject_HEAD 327 PyObject_HEAD
347 PyObject *index; 328 PyObject *index;
348 PyObject *start; 329 PyObject *start;
349 PyObject *step; 330 PyObject *step;
350 PyObject *len; 331 PyObject *length;
351 } longrangeiterobject; 332 } longrangeiterobject;
352 333
353 static PyObject * 334 static PyObject *
354 longrangeiter_len(longrangeiterobject *r, PyObject *no_args) 335 longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
355 { 336 {
356 return PyNumber_Subtract(r->len, r->index); 337 return PyNumber_Subtract(r->length, r->index);
357 } 338 }
358 339
359 static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw); 340 static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
360 341
361 PyDoc_STRVAR(length_hint_doc, 342 PyDoc_STRVAR(length_hint_doc,
362 "Private method returning an estimate of len(list(it))."); 343 "Private method returning an estimate of len(list(it)).");
363 344
364 static PyMethodDef rangeiter_methods[] = { 345 static PyMethodDef rangeiter_methods[] = {
365 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, 346 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
366 length_hint_doc}, 347 length_hint_doc},
367 {NULL, NULL} /* sentinel */ 348 {NULL, NULL} /* sentinel */
368 }; 349 };
369 350
370 PyTypeObject PyRangeIter_Type = { 351 PyTypeObject PyRangeIter_Type = {
371 PyVarObject_HEAD_INIT(&PyType_Type, 0) 352 PyVarObject_HEAD_INIT(&PyType_Type, 0)
372 "range_iterator", /* tp_name */ 353 "range_iterator", /* tp_name */
373 sizeof(rangeiterobject), /* tp_basicsize */ 354 sizeof(rangeiterobject), /* tp_basicsize */
374 0, /* tp_itemsize */ 355 0, /* tp_itemsize */
375 /* methods */ 356 /* methods */
376 (destructor)PyObject_Del, /* tp_dealloc */ 357 (destructor)PyObject_Del, /* tp_dealloc */
377 0, /* tp_print */ 358 0, /* tp_print */
378 0, /* tp_getattr */ 359 0, /* tp_getattr */
379 0, /* tp_setattr */ 360 0, /* tp_setattr */
380 0, /* tp_compare */ 361 0, /* tp_compare */
381 0, /* tp_repr */ 362 0, /* tp_repr */
382 0, /* tp_as_number */ 363 0, /* tp_as_number */
383 0, /* tp_as_sequence */ 364 0, /* tp_as_sequence */
384 0, /* tp_as_mapping */ 365 0, /* tp_as_mapping */
385 0, /* tp_hash */ 366 0, /* tp_hash */
386 0, /* tp_call */ 367 0, /* tp_call */
387 0, /* tp_str */ 368 0, /* tp_str */
388 PyObject_GenericGetAttr, /* tp_getattro */ 369 PyObject_GenericGetAttr, /* tp_getattro */
389 0, /* tp_setattro */ 370 0, /* tp_setattro */
390 0, /* tp_as_buffer */ 371 0, /* tp_as_buffer */
391 Py_TPFLAGS_DEFAULT, /* tp_flags */ 372 Py_TPFLAGS_DEFAULT, /* tp_flags */
392 0, /* tp_doc */ 373 0, /* tp_doc */
393 0, /* tp_traverse */ 374 0, /* tp_traverse */
394 0, /* tp_clear */ 375 0, /* tp_clear */
395 0, /* tp_richcompare */ 376 0, /* tp_richcompare */
396 0, /* tp_weaklistoffset */ 377 0, /* tp_weaklistoffset */
397 PyObject_SelfIter, /* tp_iter */ 378 PyObject_SelfIter, /* tp_iter */
398 (iternextfunc)rangeiter_next, /* tp_iternext */ 379 (iternextfunc)rangeiter_next, /* tp_iternext */
399 rangeiter_methods, /* tp_methods */ 380 rangeiter_methods, /* tp_methods */
400 0, /* tp_members */ 381 0, /* tp_members */
401 0, /* tp_getset */ 382 0, /* tp_getset */
402 0, /* tp_base */ 383 0, /* tp_base */
403 0, /* tp_dict */ 384 0, /* tp_dict */
404 0, /* tp_descr_get */ 385 0, /* tp_descr_get */
405 0, /* tp_descr_set */ 386 0, /* tp_descr_set */
406 0, /* tp_dictoffset */ 387 0, /* tp_dictoffset */
407 0, /* tp_init */ 388 0, /* tp_init */
408 0, /* tp_alloc */ 389 0, /* tp_alloc */
409 rangeiter_new, /* tp_new */ 390 rangeiter_new, /* tp_new */
410 }; 391 };
411 392
412 /* Return number of items in range/xrange (lo, hi, step). step > 0 393 /* Return number of items in range/xrange (lo, hi, step). step > 0
413 * required. Return a value < 0 if & only if the true value is too 394 * required. Return a value < 0 if & only if the true value is too
414 * large to fit in a signed long. 395 * large to fit in a signed long.
415 */ 396 */
416 static long 397 static long
417 get_len_of_range(long lo, long hi, long step) 398 get_len_of_range(long lo, long hi, long step)
418 { 399 {
419 /* ------------------------------------------------------------- 400 /* -------------------------------------------------------------
420 If lo >= hi, the range is empty. 401 If lo >= hi, the range is empty.
421 Else if n values are in the range, the last one is 402 Else if n values are in the range, the last one is
422 lo + (n-1)*step, which must be <= hi-1. Rearranging, 403 lo + (n-1)*step, which must be <= hi-1. Rearranging,