Fix attribute access for the xrange objects. The tp_getattr and tp_getattro
handlers were both set, but were not compatible. This change uses only the tp_getattro handler with a more "modern" approach. This fixes SF bug #551285.
This commit is contained in:
parent
9546772ccd
commit
edb51bb7e8
|
@ -264,34 +264,41 @@ range_tolist(rangeobject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
range_getattr(rangeobject *r, char *name)
|
range_get_stop(rangeobject *self, void *closure)
|
||||||
|
{
|
||||||
|
return PyInt_FromLong(self->start + (self->len * self->step));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef range_methods[] = {
|
||||||
|
{"tolist", (PyCFunction)range_tolist, METH_NOARGS,
|
||||||
|
"tolist() -> list\n"
|
||||||
|
"Return a list object with the same values.\n"
|
||||||
|
"(This method is deprecated; use list() instead.)"},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyMemberDef range_members[] = {
|
||||||
|
{"step", T_LONG, offsetof(rangeobject, step), RO,
|
||||||
|
"Interval between indexes of the slice; also known as the 'stride'."},
|
||||||
|
{"start", T_LONG, offsetof(rangeobject, start), RO,
|
||||||
|
"First index of the slice."},
|
||||||
|
{NULL, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyGetSetDef range_getsets[] = {
|
||||||
|
{"stop", (getter)range_get_stop, NULL,
|
||||||
|
""},
|
||||||
|
{NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
range_getattro(rangeobject *self, PyObject *name)
|
||||||
{
|
{
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
result = PyObject_GenericGetAttr((PyObject *)self, name);
|
||||||
static PyMethodDef range_methods[] = {
|
if (result && PyInt_CheckExact(result)) {
|
||||||
{"tolist", (PyCFunction)range_tolist, METH_NOARGS,
|
WARN("xrange object's 'start', 'stop' and 'step' "
|
||||||
"tolist() -> list\n"
|
"attributes are deprecated");
|
||||||
"Return a list object with the same values.\n"
|
|
||||||
"(This method is deprecated; use list() instead.)"},
|
|
||||||
{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}
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (result)
|
|
||||||
WARN("xrange object's 'start', 'stop' and 'step' "
|
|
||||||
"attributes are deprecated");
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -315,7 +322,7 @@ PyTypeObject PyRange_Type = {
|
||||||
0, /* Item size for varobject */
|
0, /* Item size for varobject */
|
||||||
(destructor)range_dealloc, /*tp_dealloc*/
|
(destructor)range_dealloc, /*tp_dealloc*/
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
(getattrfunc)range_getattr, /*tp_getattr*/
|
0, /*tp_getattr*/
|
||||||
0, /*tp_setattr*/
|
0, /*tp_setattr*/
|
||||||
(cmpfunc)range_compare, /*tp_compare*/
|
(cmpfunc)range_compare, /*tp_compare*/
|
||||||
(reprfunc)range_repr, /*tp_repr*/
|
(reprfunc)range_repr, /*tp_repr*/
|
||||||
|
@ -325,7 +332,7 @@ PyTypeObject PyRange_Type = {
|
||||||
0, /*tp_hash*/
|
0, /*tp_hash*/
|
||||||
0, /*tp_call*/
|
0, /*tp_call*/
|
||||||
0, /*tp_str*/
|
0, /*tp_str*/
|
||||||
PyObject_GenericGetAttr, /*tp_getattro*/
|
(getattrofunc)range_getattro, /*tp_getattro*/
|
||||||
0, /*tp_setattro*/
|
0, /*tp_setattro*/
|
||||||
0, /*tp_as_buffer*/
|
0, /*tp_as_buffer*/
|
||||||
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||||
|
@ -336,9 +343,9 @@ PyTypeObject PyRange_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
0, /* tp_iter */
|
0, /* tp_iter */
|
||||||
0, /* tp_iternext */
|
0, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
range_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
range_members, /* tp_members */
|
||||||
0, /* tp_getset */
|
range_getsets, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
0, /* tp_dict */
|
0, /* tp_dict */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue