mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
a91e1650aa
commit
0b796fa5c5
|
@ -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)
|
||||||
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,21 +211,29 @@ range_contains(rangeobject *r, PyObject *obj)
|
||||||
if (num < 0 && PyErr_Occurred())
|
if (num < 0 && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((num < r->start) || ((num - r->start) % r->step))
|
if (r->step > 0) {
|
||||||
return 0;
|
if ((num < r->start) || ((num - r->start) % r->step))
|
||||||
if (num >= (r->start + (r->len * r->step)))
|
return 0;
|
||||||
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods range_as_sequence = {
|
static PySequenceMethods range_as_sequence = {
|
||||||
(inquiry)range_length, /*sq_length*/
|
(inquiry)range_length, /*sq_length*/
|
||||||
(binaryfunc)range_concat, /*sq_concat*/
|
(binaryfunc)range_concat, /*sq_concat*/
|
||||||
(intargfunc)range_repeat, /*sq_repeat*/
|
(intargfunc)range_repeat, /*sq_repeat*/
|
||||||
(intargfunc)range_item, /*sq_item*/
|
(intargfunc)range_item, /*sq_item*/
|
||||||
(intintargfunc)range_slice, /*sq_slice*/
|
(intintargfunc)range_slice, /*sq_slice*/
|
||||||
0, /*sq_ass_item*/
|
0, /*sq_ass_item*/
|
||||||
0, /*sq_ass_slice*/
|
0, /*sq_ass_slice*/
|
||||||
(objobjproc)range_contains, /*sq_contains*/
|
(objobjproc)range_contains, /*sq_contains*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue