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

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: in response to reviews Created 5 months, 1 week 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
GvR 2008/05/03 05:04:35 Hm. I didn't mean for you to delete the entire com
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;
(...skipping 19 matching lines...) Show 10 above Show 10 below
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 PyObject *
194 range_length(rangeobject *r) 198 range_length_hint(rangeobject *r)
195 { 199 {
196 PyObject *len = range_length_obj(r); 200 Py_INCREF(r->length);
197 Py_ssize_t result = -1; 201 return r->length;
198 if (len) {
199 result = PyLong_AsSsize_t(len);
200 Py_DECREF(len);
201 }
202 return result;
203 } 202 }
204 203
205 /* range(...)[x] is necessary for: seq[:] = range(...) */ 204 PyDoc_STRVAR(range_length_hint_doc,
205 "__length_hint__() -> int\n"
206 "Return a estimate of len(list(range)).");
206 207
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 208
235 static PyObject * 209 static PyObject *
236 range_repr(rangeobject *r) 210 range_repr(rangeobject *r)
237 { 211 {
238 Py_ssize_t istep; 212 Py_ssize_t istep;
239 213
240 /* Check for special case values for printing. We don't always 214 /* Check for special case values for printing. We don't always
241 need the step value. We don't care about errors 215 need the step value. We don't care about errors
242 (it means overflow), so clear the errors. */ 216 (it means overflow), so clear the errors. */
243 istep = PyNumber_AsSsize_t(r->step, NULL); 217 istep = PyNumber_AsSsize_t(r->step, NULL);
244 if (istep != 1 || (istep == -1 && PyErr_Occurred())) { 218 if (istep != 1 || (istep == -1 && PyErr_Occurred())) {
245 PyErr_Clear(); 219 PyErr_Clear();
246 } 220 }
247 221
248 if (istep == 1) 222 if (istep == 1)
249 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop); 223 return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop);
250 else 224 else
251 return PyUnicode_FromFormat("range(%R, %R, %R)", 225 return PyUnicode_FromFormat("range(%R, %R, %R)",
252 r->start, r->stop, r->step); 226 r->start, r->stop, r->step);
253 } 227 }
254 228
255 static PySequenceMethods range_as_sequence = { 229 static PyMemberDef range_members[] = {
256 (lenfunc)range_length, /* sq_length */ 230 {"start", T_OBJECT, offsetof(rangeobject, start), READONLY},
257 0, /* sq_concat */ 231 {"stop", T_OBJECT, offsetof(rangeobject, stop), READONLY},
258 0, /* sq_repeat */ 232 {"step", T_OBJECT, offsetof(rangeobject, step), READONLY},
259 (ssizeargfunc)range_item, /* sq_item */ 233 {0}
260 0, /* sq_slice */
261 }; 234 };
262 235
263 static PyObject * range_iter(PyObject *seq); 236 static PyObject * range_iter(PyObject *seq);
264 static PyObject * range_reverse(PyObject *seq); 237 static PyObject * range_reverse(PyObject *seq);
265 238
266 PyDoc_STRVAR(reverse_doc, 239 PyDoc_STRVAR(reverse_doc,
267 "Returns a reverse iterator."); 240 "Returns a reverse iterator.");
268 241
269 static PyMethodDef range_methods[] = { 242 static PyMethodDef range_methods[] = {
270 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, 243 {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
271 reverse_doc}, 244 reverse_doc},
245 {"__length_hint__", (PyCFunction)range_length_hint, METH_NOARGS,
246 range_length_hint_doc},
272 {NULL, NULL} /* sentinel */ 247 {NULL, NULL} /* sentinel */
273 }; 248 };
274 249
275 PyTypeObject PyRange_Type = { 250 PyTypeObject PyRange_Type = {
276 PyVarObject_HEAD_INIT(&PyType_Type, 0) 251 PyVarObject_HEAD_INIT(&PyType_Type, 0)
277 "range", /* Name of this type */ 252 "range", /* Name of this type */
278 sizeof(rangeobject), /* Basic object size */ 253 sizeof(rangeobject), /* Basic object size */
279 0, /* Item size for varobject */ 254 0, /* Item size for varobject */
280 (destructor)range_dealloc, /* tp_dealloc */ 255 (destructor)range_dealloc, /* tp_dealloc */
281 0, /* tp_print */ 256 0, /* tp_print */
282 0, /* tp_getattr */ 257 0, /* tp_getattr */
283 0, /* tp_setattr */ 258 0, /* tp_setattr */
284 0, /* tp_compare */ 259 0, /* tp_compare */
285 (reprfunc)range_repr, /* tp_repr */ 260 (reprfunc)range_repr, /* tp_repr */
286 0, /* tp_as_number */ 261 0, /* tp_as_number */
287 &range_as_sequence, /* tp_as_sequence */ 262 0, /* tp_as_sequence */
288 0, /* tp_as_mapping */ 263 0, /* tp_as_mapping */
289 0, /* tp_hash */ 264 0, /* tp_hash */
290 0, /* tp_call */ 265 0, /* tp_call */
291 0, /* tp_str */ 266 0, /* tp_str */
292 PyObject_GenericGetAttr, /* tp_getattro */ 267 PyObject_GenericGetAttr, /* tp_getattro */
293 0, /* tp_setattro */ 268 0, /* tp_setattro */
294 0, /* tp_as_buffer */ 269 0, /* tp_as_buffer */
295 Py_TPFLAGS_DEFAULT, /* tp_flags */ 270 Py_TPFLAGS_DEFAULT, /* tp_flags */
296 range_doc, /* tp_doc */ 271 range_doc, /* tp_doc */
297 0, /* tp_traverse */ 272 0, /* tp_traverse */
298 0, /* tp_clear */ 273 0, /* tp_clear */
299 0, /* tp_richcompare */ 274 0, /* tp_richcompare */
300 0, /* tp_weaklistoffset */ 275 0, /* tp_weaklistoffset */
301 range_iter, /* tp_iter */ 276 range_iter, /* tp_iter */
302 0, /* tp_iternext */ 277 0, /* tp_iternext */
303 range_methods, /* tp_methods */ 278 range_methods, /* tp_methods */
304 0, /* tp_members */ 279 range_members, /* tp_members */
305 0, /* tp_getset */ 280 0, /* tp_getset */
306 0, /* tp_base */ 281 0, /* tp_base */
307 0, /* tp_dict */ 282 0, /* tp_dict */
308 0, /* tp_descr_get */ 283 0, /* tp_descr_get */
309 0, /* tp_descr_set */ 284 0, /* tp_descr_set */
310 0, /* tp_dictoffset */ 285 0, /* tp_dictoffset */
311 0, /* tp_init */ 286 0, /* tp_init */
312 0, /* tp_alloc */ 287 0, /* tp_alloc */
313 range_new, /* tp_new */ 288 range_new, /* tp_new */
314 }; 289 };
315 290
(...skipping 24 matching lines...) Show 10 above Show 10 below
340 rangeiter_len(rangeiterobject *r) 315 rangeiter_len(rangeiterobject *r)
341 { 316 {
342 return PyLong_FromLong(r->len - r->index); 317 return PyLong_FromLong(r->len - r->index);
343 } 318 }
344 319
345 typedef struct { 320 typedef struct {
346 PyObject_HEAD 321 PyObject_HEAD
347 PyObject *index; 322 PyObject *index;
348 PyObject *start; 323 PyObject *start;
349 PyObject *step; 324 PyObject *step;
350 PyObject *len; 325 PyObject *length;
351 } longrangeiterobject; 326 } longrangeiterobject;
352 327
353 static PyObject * 328 static PyObject *
354 longrangeiter_len(longrangeiterobject *r, PyObject *no_args) 329 longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
355 { 330 {
356 return PyNumber_Subtract(r->len, r->index); 331 return PyNumber_Subtract(r->length, r->index);
357 } 332 }
358 333
359 static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw); 334 static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
360 335
361 PyDoc_STRVAR(length_hint_doc, 336 PyDoc_STRVAR(length_hint_doc,
362 "Private method returning an estimate of len(list(it))."); 337 "Private method returning an estimate of len(list(it)).");
363 338
364 static PyMethodDef rangeiter_methods[] = { 339 static PyMethodDef rangeiter_methods[] = {
365 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, 340 {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS,
366 length_hint_doc}, 341 length_hint_doc},
(...skipping 107 matching lines...) Show 10 above Show 10 below
474 length_hint_doc}, 449 length_hint_doc},
475 {NULL, NULL} /* sentinel */ 450 {NULL, NULL} /* sentinel */
476 }; 451 };
477 452
478 static void 453 static void
479 longrangeiter_dealloc(longrangeiterobject *r) 454 longrangeiter_dealloc(longrangeiterobject *r)
480 { 455 {
481 Py_XDECREF(r->index); 456 Py_XDECREF(r->index);
482 Py_XDECREF(r->start); 457 Py_XDECREF(r->start);
483 Py_XDECREF(r->step); 458 Py_XDECREF(r->step);
484 Py_XDECREF(r->len); 459 Py_XDECREF(r->length);
485 PyObject_Del(r); 460 PyObject_Del(r);
486 } 461 }
487 462
488 static PyObject * 463 static PyObject *
489 longrangeiter_next(longrangeiterobject *r) 464 longrangeiter_next(longrangeiterobject *r)
490 { 465 {
491 PyObject *one, *product, *new_index, *result; 466 PyObject *one, *product, *new_index, *result;
492 if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) 467 if (PyObject_RichCompareBool(r->index, r->length, Py_LT) != 1)
493 return NULL; 468 return NULL;
494 469
495 one = PyLong_FromLong(1); 470 one = PyLong_FromLong(1);
496 if (!one) 471 if (!one)
497 return NULL; 472 return NULL;
498 473
499 product = PyNumber_Multiply(r->index, r->step); 474 product = PyNumber_Multiply(r->index, r->step);
500 if (!product) { 475 if (!product) {
501 Py_DECREF(one); 476 Py_DECREF(one);
502 return NULL; 477 return NULL;
(...skipping 47 matching lines...) Show 10 above Show 10 below
550 (iternextfunc)longrangeiter_next, /* tp_iternext */ 525 (iternextfunc)longrangeiter_next, /* tp_iternext */
551 longrangeiter_methods, /* tp_methods */ 526 longrangeiter_methods, /* tp_methods */
552 0, 527 0,
553 }; 528 };
554 529
555 static PyObject * 530 static PyObject *
556 range_iter(PyObject *seq) 531 range_iter(PyObject *seq)
557 { 532 {
558 rangeobject *r = (rangeobject *)seq; 533 rangeobject *r = (rangeobject *)seq;
559 longrangeiterobject *it; 534 longrangeiterobject *it;
560 PyObject *tmp, *len;
561 long lstart, lstop, lstep; 535 long lstart, lstop, lstep;
562 536
563 assert(PyRange_Check(seq)); 537 assert(PyRange_Check(seq));
564 538
565 /* If all three fields convert to long, use the int version */ 539 /* If all three fields convert to long, use the int version */
566 lstart = PyLong_AsLong(r->start); 540 lstart = PyLong_AsLong(r->start);
567 if (lstart != -1 || !PyErr_Occurred()) { 541 if (lstart != -1 || !PyErr_Occurred()) {
568 lstop = PyLong_AsLong(r->stop); 542 lstop = PyLong_AsLong(r->stop);
569 if (lstop != -1 || !PyErr_Occurred()) { 543 if (lstop != -1 || !PyErr_Occurred()) {
570 lstep = PyLong_AsLong(r->step); 544 lstep = PyLong_AsLong(r->step);
571 if (lstep != -1 || !PyErr_Occurred()) 545 if (lstep != -1 || !PyErr_Occurred())
572 return int_range_iter(lstart, lstop, lstep); 546 return int_range_iter(lstart, lstop, lstep);
573 } 547 }
574 } 548 }
575 /* Some conversion failed, so there is an error set. Clear it, 549 /* Some conversion failed, so there is an error set. Clear it,
576 and try again with a long range. */ 550 and try again with a long range. */
577 PyErr_Clear(); 551 PyErr_Clear();
578 552
579 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); 553 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
580 if (it == NULL) 554 if (it == NULL)
581 return NULL; 555 return NULL;
582 556
583 /* Do all initialization here, so we can DECREF on failure. */ 557 /* Do all initialization here, so we can DECREF on failure. */
584 it->start = r->start; 558 it->start = r->start;
585 it->step = r->step; 559 it->step = r->step;
586 Py_INCREF(it->start); 560 Py_INCREF(it->start);
587 Py_INCREF(it->step); 561 Py_INCREF(it->step);
588 562
589 it->len = it->index = NULL; 563 Py_INCREF(r->length);
590 564 it->length = r->length;
591 /* Calculate length: (r->stop - r->start) / r->step */
592 tmp = PyNumber_Subtract(r->stop, r->start);
593 if (!tmp)
594 goto create_failure;
595 len = PyNumber_FloorDivide(tmp, r->step);
596 Py_DECREF(tmp);
597 if (!len)
598 goto create_failure;
599 it->len = len;
600 it->index = PyLong_FromLong(0); 565 it->index = PyLong_FromLong(0);
601 if (!it->index) 566 if (!it->index)
602 goto create_failure; 567 goto create_failure;
603 568
604 return (PyObject *)it; 569 return (PyObject *)it;
605 570
606 create_failure: 571 create_failure:
607 Py_DECREF(it); 572 Py_DECREF(it);
608 return NULL; 573 return NULL;
609 } 574 }
(...skipping 30 matching lines...) Show 10 above Show 10 below
640 } 605 }
641 } 606 }
642 } 607 }
643 PyErr_Clear(); 608 PyErr_Clear();
644 609
645 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); 610 it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
646 if (it == NULL) 611 if (it == NULL)
647 return NULL; 612 return NULL;
648 613
649 /* start + (len - 1) * step */ 614 /* start + (len - 1) * step */
650 len = range_length_obj(range); 615 Py_INCREF(range->length);
651 if (!len) 616 len = range->length;
652 goto create_failure;
653 617
654 one = PyLong_FromLong(1); 618 one = PyLong_FromLong(1);
655 if (!one) 619 if