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

Delta Between Two Patch Sets: Objects/rangeobject.c

Issue 28376: assertion failure in rangeobject.c
Left Patch Set: Created 3 years, 7 months ago
Right Patch Set: Created 3 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_range.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* Range object implementation */ 1 /* Range object implementation */
2 2
3 #include "Python.h" 3 #include "Python.h"
4 #include "structmember.h" 4 #include "structmember.h"
5 5
6 /* Support objects whose length is > PY_SSIZE_T_MAX. 6 /* Support objects whose length is > PY_SSIZE_T_MAX.
7 7
8 This could be sped up for small PyLongs if they fit in a Py_ssize_t. 8 This could be sped up for small PyLongs if they fit in a Py_ssize_t.
9 This only matters on Win64. Though we could use PY_LONG_LONG which 9 This only matters on Win64. Though we could use long long which
10 would presumably help perf. 10 would presumably help perf.
11 */ 11 */
12 12
13 typedef struct { 13 typedef struct {
14 PyObject_HEAD 14 PyObject_HEAD
15 PyObject *start; 15 PyObject *start;
16 PyObject *stop; 16 PyObject *stop;
17 PyObject *step; 17 PyObject *step;
18 PyObject *length; 18 PyObject *length;
19 } rangeobject; 19 } rangeobject;
20 20
21 /* Helper function for validating step. Always returns a new reference or 21 /* Helper function for validating step. Always returns a new reference or
22 NULL on error. 22 NULL on error.
23 */ 23 */
24 static PyObject * 24 static PyObject *
25 validate_step(PyObject *step) 25 validate_step(PyObject *step)
26 { 26 {
27 /* No step specified, use a step of 1. */ 27 /* No step specified, use a step of 1. */
28 if (!step) 28 if (!step)
29 return PyLong_FromLong(1); 29 return PyLong_FromLong(1);
30 30
31 step = PyNumber_Index(step); 31 step = PyNumber_Index(step);
32 if (step) { 32 if (step && _PyLong_Sign(step) == 0) {
33 Py_ssize_t istep = PyNumber_AsSsize_t(step, NULL); 33 PyErr_SetString(PyExc_ValueError,
34 if (istep == -1 && PyErr_Occurred()) { 34 "range() arg 3 must not be zero");
35 /* Ignore OverflowError, we know the value isn't 0. */ 35 Py_CLEAR(step);
36 PyErr_Clear();
37 }
38 else if (istep == 0) {
39 PyErr_SetString(PyExc_ValueError,
40 "range() arg 3 must not be zero");
41 Py_CLEAR(step);
42 }
43 } 36 }
44 37
45 return step; 38 return step;
46 } 39 }
47 40
48 static PyObject * 41 static PyObject *
49 compute_range_length(PyObject *start, PyObject *stop, PyObject *step); 42 compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
50 43
51 static rangeobject * 44 static rangeobject *
52 make_range_object(PyTypeObject *type, PyObject *start, 45 make_range_object(PyTypeObject *type, PyObject *start,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 Py_DECREF(stop); 115 Py_DECREF(stop);
123 return NULL; 116 return NULL;
124 } 117 }
125 } 118 }
126 119
127 obj = make_range_object(type, start, stop, step); 120 obj = make_range_object(type, start, stop, step);
128 if (obj != NULL) 121 if (obj != NULL)
129 return (PyObject *) obj; 122 return (PyObject *) obj;
130 123
131 /* Failed to create object, release attributes */ 124 /* Failed to create object, release attributes */
132 Py_XDECREF(start); 125 Py_DECREF(start);
133 Py_XDECREF(stop); 126 Py_DECREF(stop);
134 Py_XDECREF(step); 127 Py_DECREF(step);
135 return NULL; 128 return NULL;
136 } 129 }
137 130
138 PyDoc_STRVAR(range_doc, 131 PyDoc_STRVAR(range_doc,
139 "range(stop) -> range object\n\ 132 "range(stop) -> range object\n\
140 range(start, stop[, step]) -> range object\n\ 133 range(start, stop[, step]) -> range object\n\
141 \n\ 134 \n\
142 Return an object that produces a sequence of integers from start (inclusive)\n\ 135 Return an object that produces a sequence of integers from start (inclusive)\n\
143 to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\ 136 to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n\
144 start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\ 137 start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n\
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 lo = stop; 182 lo = stop;
190 hi = start; 183 hi = start;
191 step = PyNumber_Negative(step); 184 step = PyNumber_Negative(step);
192 if (!step) 185 if (!step)
193 return NULL; 186 return NULL;
194 } 187 }
195 188
196 /* if (lo >= hi), return length of 0. */ 189 /* if (lo >= hi), return length of 0. */
197 cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE); 190 cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE);
198 if (cmp_result != 0) { 191 if (cmp_result != 0) {
199 Py_XDECREF(step); 192 Py_DECREF(step);
200 if (cmp_result < 0) 193 if (cmp_result < 0)
201 return NULL; 194 return NULL;
202 return PyLong_FromLong(0); 195 return PyLong_FromLong(0);
203 } 196 }
204 197
205 if ((one = PyLong_FromLong(1L)) == NULL) 198 if ((one = PyLong_FromLong(1L)) == NULL)
206 goto Fail; 199 goto Fail;
207 200
208 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) 201 if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
209 goto Fail; 202 goto Fail;
210 203
211 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL) 204 if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
212 goto Fail; 205 goto Fail;
213 206
214 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL) 207 if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
215 goto Fail; 208 goto Fail;
216 209
217 if ((result = PyNumber_Add(tmp2, one)) == NULL) 210 if ((result = PyNumber_Add(tmp2, one)) == NULL)
218 goto Fail; 211 goto Fail;
219 212
220 Py_DECREF(tmp2); 213 Py_DECREF(tmp2);
221 Py_DECREF(diff); 214 Py_DECREF(diff);
222 Py_DECREF(step); 215 Py_DECREF(step);
223 Py_DECREF(tmp1); 216 Py_DECREF(tmp1);
224 Py_DECREF(one); 217 Py_DECREF(one);
225 return result; 218 return result;
226 219
227 Fail: 220 Fail:
221 Py_DECREF(step);
228 Py_XDECREF(tmp2); 222 Py_XDECREF(tmp2);
229 Py_XDECREF(diff); 223 Py_XDECREF(diff);
230 Py_XDECREF(step);
231 Py_XDECREF(tmp1); 224 Py_XDECREF(tmp1);
232 Py_XDECREF(one); 225 Py_XDECREF(one);
233 return NULL; 226 return NULL;
234 } 227 }
235 228
236 static Py_ssize_t 229 static Py_ssize_t
237 range_length(rangeobject *r) 230 range_length(rangeobject *r)
238 { 231 {
239 return PyLong_AsSsize_t(r->length); 232 return PyLong_AsSsize_t(r->length);
240 } 233 }
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 it->len = (long)ulen; 923 it->len = (long)ulen;
931 it->index = 0; 924 it->index = 0;
932 return (PyObject *)it; 925 return (PyObject *)it;
933 } 926 }
934 927
935 static PyObject * 928 static PyObject *
936 rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) 929 rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
937 { 930 {
938 long start, stop, step; 931 long start, stop, step;
939 932
933 if (PyErr_WarnEx(PyExc_DeprecationWarning,
934 "range_iterator(): creating instances of range_iterator "
935 "by calling range_iterator type is deprecated",
936 1)) {
937 return NULL;
938 }
939
940 if (!_PyArg_NoKeywords("range_iterator()", kw)) { 940 if (!_PyArg_NoKeywords("range_iterator()", kw)) {
941 return NULL; 941 return NULL;
942 } 942 }
943 943
944 if (!PyArg_ParseTuple(args, 944 if (!PyArg_ParseTuple(args,
945 "lll;range_iterator() requires 3 int arguments", 945 "lll;range_iterator() requires 3 int arguments",
946 &start, &stop, &step)) { 946 &start, &stop, &step)) {
947 return NULL; 947 return NULL;
948 } 948 }
949 if (step == 0) { 949 if (step == 0) {
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 it->index = PyLong_FromLong(0); 1278 it->index = PyLong_FromLong(0);
1279 if (!it->index) 1279 if (!it->index)
1280 goto create_failure; 1280 goto create_failure;
1281 1281
1282 return (PyObject *)it; 1282 return (PyObject *)it;
1283 1283
1284 create_failure: 1284 create_failure:
1285 Py_DECREF(it); 1285 Py_DECREF(it);
1286 return NULL; 1286 return NULL;
1287 } 1287 }
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+