diff options
author | Fred Drake <fdrake@acm.org> | 2000-11-08 19:42:43 (GMT) |
---|---|---|
committer | Fred Drake <fdrake@acm.org> | 2000-11-08 19:42:43 (GMT) |
commit | 0b796fa5c56611341f039c5ab6ed17a2b63833d2 (patch) | |
tree | ff6832a88968ff22c90a139efa141dbb15fcf209 | |
parent | a91e1650aafd63e7940a1c838aa1377981ad459c (diff) | |
download | cpython-0b796fa5c56611341f039c5ab6ed17a2b63833d2.zip cpython-0b796fa5c56611341f039c5ab6ed17a2b63833d2.tar.gz cpython-0b796fa5c56611341f039c5ab6ed17a2b63833d2.tar.bz2 |
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.
-rw-r--r-- | Objects/rangeobject.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 0deabe9..1aac2dc 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -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*/ }; |