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 @@ ...@@ -2,6 +2,8 @@
/* Range object implementation */ /* Range object implementation */
#include "Python.h" #include "Python.h"
#include "structmember.h"
#include <string.h>
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
...@@ -175,14 +177,30 @@ range_tolist(rangeobject *self, PyObject *args) ...@@ -175,14 +177,30 @@ range_tolist(rangeobject *self, PyObject *args)
static PyObject * static PyObject *
range_getattr(rangeobject *r, char *name) range_getattr(rangeobject *r, char *name)
{ {
PyObject *result;
static PyMethodDef range_methods[] = { static PyMethodDef range_methods[] = {
{"tolist", (PyCFunction)range_tolist, METH_VARARGS, {"tolist", (PyCFunction)range_tolist, METH_VARARGS,
"tolist() -> list\n" "tolist() -> list\n"
"Return a list object with the same values."}, "Return a list object with the same values."},
{NULL, NULL} {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 static int
...@@ -193,10 +211,18 @@ range_contains(rangeobject *r, PyObject *obj) ...@@ -193,10 +211,18 @@ range_contains(rangeobject *r, PyObject *obj)
if (num < 0 && PyErr_Occurred()) if (num < 0 && PyErr_Occurred())
return -1; return -1;
if (r->step > 0) {
if ((num < r->start) || ((num - r->start) % r->step)) if ((num < r->start) || ((num - r->start) % r->step))
return 0; return 0;
if (num >= (r->start + (r->len * r->step))) if (num >= (r->start + (r->len * r->step)))
return 0; 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; return 1;
} }
......
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