Commit 0b796fa5 authored by Fred Drake's avatar Fred Drake

Fixed support for containment test when a negative step is used; this

*really* closes bug #121965.

Added three attributes to the xrange object: start, stop, and step.  These
are the same as for the slice objects.
parent a91e1650
......@@ -2,6 +2,8 @@
/* Range object implementation */
#include "Python.h"
#include "structmember.h"
#include <string.h>
typedef struct {
PyObject_HEAD
......@@ -175,14 +177,30 @@ range_tolist(rangeobject *self, PyObject *args)
static PyObject *
range_getattr(rangeobject *r, char *name)
{
PyObject *result;
static PyMethodDef range_methods[] = {
{"tolist", (PyCFunction)range_tolist, METH_VARARGS,
"tolist() -> list\n"
"Return a list object with the same values."},
{NULL, NULL}
};
static struct memberlist range_members[] = {
{"step", T_LONG, offsetof(rangeobject, step), RO},
{"start", T_LONG, offsetof(rangeobject, start), RO},
{"stop", T_LONG, 0, RO},
{NULL, 0, 0, 0}
};
return Py_FindMethod(range_methods, (PyObject *) r, name);
result = Py_FindMethod(range_methods, (PyObject *) r, name);
if (result == NULL) {
PyErr_Clear();
if (strcmp("stop", name) == 0)
result = PyInt_FromLong(r->start + (r->len * r->step));
else
result = PyMember_Get((char *)r, range_members, name);
}
return result;
}
static int
......@@ -193,21 +211,29 @@ range_contains(rangeobject *r, PyObject *obj)
if (num < 0 && PyErr_Occurred())
return -1;
if ((num < r->start) || ((num - r->start) % r->step))
return 0;
if (num >= (r->start + (r->len * r->step)))
return 0;
if (r->step > 0) {
if ((num < r->start) || ((num - r->start) % r->step))
return 0;
if (num >= (r->start + (r->len * r->step)))
return 0;
}
else {
if ((num > r->start) || ((num - r->start) % r->step))
return 0;
if (num <= (r->start + (r->len * r->step)))
return 0;
}
return 1;
}
static PySequenceMethods range_as_sequence = {
(inquiry)range_length, /*sq_length*/
(inquiry)range_length, /*sq_length*/
(binaryfunc)range_concat, /*sq_concat*/
(intargfunc)range_repeat, /*sq_repeat*/
(intargfunc)range_item, /*sq_item*/
(intintargfunc)range_slice, /*sq_slice*/
0, /*sq_ass_item*/
0, /*sq_ass_slice*/
0, /*sq_ass_item*/
0, /*sq_ass_slice*/
(objobjproc)range_contains, /*sq_contains*/
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment