Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3f56166

Browse files
committed
Rip out the fancy behaviors of xrange that nobody uses: repeat, slice,
contains, tolist(), and the start/stop/step attributes. This includes removing the 4th ('repeat') argument to PyRange_New().
1 parent 25ddc63 commit 3f56166

3 files changed

Lines changed: 18 additions & 229 deletions

File tree

Doc/lib/libstdtypes.tex

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -775,12 +775,8 @@ \subsubsection{XRange Type \label{typesseq-xrange}}
775775
size of the range it represents. There are no consistent performance
776776
advantages.
777777

778-
XRange objects behave like tuples, and offer a single method:
779-
780-
\begin{methoddesc}[xrange]{tolist}{}
781-
Return a list object which represents the same values as the xrange
782-
object.
783-
\end{methoddesc}
778+
XRange objects have very little behavior: they only support indexing
779+
and the \function{len()} function.
784780

785781

786782
\subsubsection{Mutable Sequence Types \label{typesseq-mutable}}

Include/rangeobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extern DL_IMPORT(PyTypeObject) PyRange_Type;
1919

2020
#define PyRange_Check(op) ((op)->ob_type == &PyRange_Type)
2121

22-
extern DL_IMPORT(PyObject *) PyRange_New(long, long, long, int);
22+
extern DL_IMPORT(PyObject *) PyRange_New(long, long, long);
2323

2424
#ifdef __cplusplus
2525
}

Objects/rangeobject.c

Lines changed: 15 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -10,58 +10,20 @@ typedef struct {
1010
long start;
1111
long step;
1212
long len;
13-
int reps;
14-
long totlen;
1513
} rangeobject;
1614

17-
static int
18-
long_mul(long i, long j, long *kk)
19-
{
20-
PyObject *a;
21-
PyObject *b;
22-
PyObject *c;
23-
24-
if ((a = PyInt_FromLong(i)) == NULL)
25-
return 0;
26-
27-
if ((b = PyInt_FromLong(j)) == NULL)
28-
return 0;
29-
30-
c = PyNumber_Multiply(a, b);
31-
32-
Py_DECREF(a);
33-
Py_DECREF(b);
34-
35-
if (c == NULL)
36-
return 0;
37-
38-
*kk = PyInt_AS_LONG(c);
39-
Py_DECREF(c);
40-
41-
if (*kk > INT_MAX) {
42-
PyErr_SetString(PyExc_OverflowError,
43-
"integer multiplication");
44-
return 0;
45-
}
46-
else
47-
return 1;
48-
}
49-
5015
PyObject *
51-
PyRange_New(long start, long len, long step, int reps)
16+
PyRange_New(long start, long len, long step)
5217
{
53-
long totlen = -1;
5418
rangeobject *obj = PyObject_NEW(rangeobject, &PyRange_Type);
5519

5620
if (obj == NULL)
5721
return NULL;
5822

59-
if (len == 0 || reps <= 0) {
23+
if (len == 0) {
6024
start = 0;
6125
len = 0;
6226
step = 1;
63-
reps = 1;
64-
totlen = 0;
6527
}
6628
else {
6729
long last = start + (len - 1) * step;
@@ -71,20 +33,12 @@ PyRange_New(long start, long len, long step, int reps)
7133
PyErr_SetString(PyExc_OverflowError,
7234
"integer addition");
7335
return NULL;
74-
}
75-
if (! long_mul(len, (long) reps, &totlen)) {
76-
if(!PyErr_ExceptionMatches(PyExc_OverflowError))
77-
return NULL;
78-
PyErr_Clear();
79-
totlen = -1;
8036
}
8137
}
8238

8339
obj->start = start;
8440
obj->len = len;
8541
obj->step = step;
86-
obj->reps = reps;
87-
obj->totlen = totlen;
8842

8943
return (PyObject *) obj;
9044
}
@@ -98,23 +52,19 @@ range_dealloc(rangeobject *r)
9852
static PyObject *
9953
range_item(rangeobject *r, int i)
10054
{
101-
if (i < 0 || i >= r->totlen)
102-
if (r->totlen!=-1) {
103-
PyErr_SetString(PyExc_IndexError,
55+
if (i < 0 || i >= r->len) {
56+
PyErr_SetString(PyExc_IndexError,
10457
"xrange object index out of range");
105-
return NULL;
106-
}
58+
return NULL;
59+
}
10760

10861
return PyInt_FromLong(r->start + (i % r->len) * r->step);
10962
}
11063

11164
static int
11265
range_length(rangeobject *r)
11366
{
114-
if (r->totlen == -1)
115-
PyErr_SetString(PyExc_OverflowError,
116-
"xrange object has too many items");
117-
return r->totlen;
67+
return r->len;
11868
}
11969

12070
static PyObject *
@@ -124,7 +74,6 @@ range_repr(rangeobject *r)
12474
* a bit of "(xrange(...) * ...)" text.
12575
*/
12676
char buf1[250];
127-
char buf2[250];
12877

12978
if (r->start == 0 && r->step == 1)
13079
sprintf(buf1, "xrange(%ld)", r->start + r->len * r->step);
@@ -140,174 +89,18 @@ range_repr(rangeobject *r)
14089
r->start + r->len * r->step,
14190
r->step);
14291

143-
if (r->reps != 1)
144-
sprintf(buf2, "(%s * %d)", buf1, r->reps);
145-
146-
return PyString_FromString(r->reps == 1 ? buf1 : buf2);
147-
}
148-
149-
static PyObject *
150-
range_concat(rangeobject *r, PyObject *obj)
151-
{
152-
PyErr_SetString(PyExc_TypeError, "cannot concatenate xrange objects");
153-
return NULL;
154-
}
155-
156-
static PyObject *
157-
range_repeat(rangeobject *r, int n)
158-
{
159-
long lreps = 0;
160-
161-
if (n <= 0)
162-
return (PyObject *) PyRange_New(0, 0, 1, 1);
163-
164-
else if (n == 1) {
165-
Py_INCREF(r);
166-
return (PyObject *) r;
167-
}
168-
169-
else if (! long_mul((long) r->reps, (long) n, &lreps))
170-
return NULL;
171-
172-
else
173-
return (PyObject *) PyRange_New(
174-
r->start,
175-
r->len,
176-
r->step,
177-
(int) lreps);
178-
}
179-
180-
static int
181-
range_compare(rangeobject *r1, rangeobject *r2)
182-
{
183-
if (r1->start != r2->start)
184-
return r1->start - r2->start;
185-
186-
else if (r1->step != r2->step)
187-
return r1->step - r2->step;
188-
189-
else if (r1->len != r2->len)
190-
return r1->len - r2->len;
191-
192-
else
193-
return r1->reps - r2->reps;
194-
}
195-
196-
static PyObject *
197-
range_slice(rangeobject *r, int low, int high)
198-
{
199-
if (r->reps != 1) {
200-
PyErr_SetString(PyExc_TypeError,
201-
"cannot slice a replicated xrange");
202-
return NULL;
203-
}
204-
if (low < 0)
205-
low = 0;
206-
else if (low > r->len)
207-
low = r->len;
208-
if (high < 0)
209-
high = 0;
210-
if (high < low)
211-
high = low;
212-
else if (high > r->len)
213-
high = r->len;
214-
215-
if (low == 0 && high == r->len) {
216-
Py_INCREF(r);
217-
return (PyObject *) r;
218-
}
219-
220-
return (PyObject *) PyRange_New(
221-
low * r->step + r->start,
222-
high - low,
223-
r->step,
224-
1);
225-
}
226-
227-
static PyObject *
228-
range_tolist(rangeobject *self, PyObject *args)
229-
{
230-
PyObject *thelist;
231-
int j;
232-
233-
if (! PyArg_ParseTuple(args, ":tolist"))
234-
return NULL;
235-
236-
if (self->totlen == -1)
237-
return PyErr_NoMemory();
238-
239-
if ((thelist = PyList_New(self->totlen)) == NULL)
240-
return NULL;
241-
242-
for (j = 0; j < self->totlen; ++j)
243-
if ((PyList_SetItem(thelist, j, (PyObject *) PyInt_FromLong(
244-
self->start + (j % self->len) * self->step))) < 0)
245-
return NULL;
246-
247-
return thelist;
248-
}
249-
250-
static PyObject *
251-
range_getattr(rangeobject *r, char *name)
252-
{
253-
PyObject *result;
254-
255-
static PyMethodDef range_methods[] = {
256-
{"tolist", (PyCFunction)range_tolist, METH_VARARGS,
257-
"tolist() -> list\n"
258-
"Return a list object with the same values."},
259-
{NULL, NULL}
260-
};
261-
static struct memberlist range_members[] = {
262-
{"step", T_LONG, offsetof(rangeobject, step), RO},
263-
{"start", T_LONG, offsetof(rangeobject, start), RO},
264-
{"stop", T_LONG, 0, RO},
265-
{NULL, 0, 0, 0}
266-
};
267-
268-
result = Py_FindMethod(range_methods, (PyObject *) r, name);
269-
if (result == NULL) {
270-
PyErr_Clear();
271-
if (strcmp("stop", name) == 0)
272-
result = PyInt_FromLong(r->start + (r->len * r->step));
273-
else
274-
result = PyMember_Get((char *)r, range_members, name);
275-
}
276-
return result;
277-
}
278-
279-
static int
280-
range_contains(rangeobject *r, PyObject *obj)
281-
{
282-
long num = PyInt_AsLong(obj);
283-
284-
if (num < 0 && PyErr_Occurred())
285-
return -1;
286-
287-
if (r->step > 0) {
288-
if ((num < r->start) || ((num - r->start) % r->step))
289-
return 0;
290-
if (num >= (r->start + (r->len * r->step)))
291-
return 0;
292-
}
293-
else {
294-
if ((num > r->start) || ((num - r->start) % r->step))
295-
return 0;
296-
if (num <= (r->start + (r->len * r->step)))
297-
return 0;
298-
}
299-
return 1;
92+
return PyString_FromString(buf1);
30093
}
30194

30295
static PySequenceMethods range_as_sequence = {
30396
(inquiry)range_length, /*sq_length*/
304-
(binaryfunc)range_concat, /*sq_concat*/
305-
(intargfunc)range_repeat, /*sq_repeat*/
306-
(intargfunc)range_item, /*sq_item*/
307-
(intintargfunc)range_slice, /*sq_slice*/
97+
0, /*sq_concat*/
98+
0, /*sq_repeat*/
99+
(intargfunc)range_item, /*sq_item*/
100+
0, /*sq_slice*/
308101
0, /*sq_ass_item*/
309102
0, /*sq_ass_slice*/
310-
(objobjproc)range_contains, /*sq_contains*/
103+
0, /*sq_contains*/
311104
};
312105

313106
PyTypeObject PyRange_Type = {
@@ -318,9 +111,9 @@ PyTypeObject PyRange_Type = {
318111
0, /* Item size for varobject */
319112
(destructor)range_dealloc, /*tp_dealloc*/
320113
0, /*tp_print*/
321-
(getattrfunc)range_getattr, /*tp_getattr*/
114+
0, /*tp_getattr*/
322115
0, /*tp_setattr*/
323-
(cmpfunc)range_compare, /*tp_compare*/
116+
0, /*tp_compare*/
324117
(reprfunc)range_repr, /*tp_repr*/
325118
0, /*tp_as_number*/
326119
&range_as_sequence, /*tp_as_sequence*/

0 commit comments

Comments
 (0)