22/* Range object implementation */
33
44#include "Python.h"
5+ #include "structmember.h"
6+ #include <string.h>
57
68typedef struct {
79 PyObject_HEAD
@@ -175,14 +177,30 @@ range_tolist(rangeobject *self, PyObject *args)
175177static PyObject *
176178range_getattr (rangeobject * r , char * name )
177179{
180+ PyObject * result ;
181+
178182 static PyMethodDef range_methods [] = {
179183 {"tolist" , (PyCFunction )range_tolist , METH_VARARGS ,
180184 "tolist() -> list\n"
181185 "Return a list object with the same values." },
182186 {NULL , NULL }
183187 };
188+ static struct memberlist range_members [] = {
189+ {"step" , T_LONG , offsetof(rangeobject , step ), RO },
190+ {"start" , T_LONG , offsetof(rangeobject , start ), RO },
191+ {"stop" , T_LONG , 0 , RO },
192+ {NULL , 0 , 0 , 0 }
193+ };
184194
185- return Py_FindMethod (range_methods , (PyObject * ) r , name );
195+ result = Py_FindMethod (range_methods , (PyObject * ) r , name );
196+ if (result == NULL ) {
197+ PyErr_Clear ();
198+ if (strcmp ("stop" , name ) == 0 )
199+ result = PyInt_FromLong (r -> start + (r -> len * r -> step ));
200+ else
201+ result = PyMember_Get ((char * )r , range_members , name );
202+ }
203+ return result ;
186204}
187205
188206static int
@@ -193,21 +211,29 @@ range_contains(rangeobject *r, PyObject *obj)
193211 if (num < 0 && PyErr_Occurred ())
194212 return -1 ;
195213
196- if ((num < r -> start ) || ((num - r -> start ) % r -> step ))
197- return 0 ;
198- if (num >= (r -> start + (r -> len * r -> step )))
199- return 0 ;
214+ if (r -> step > 0 ) {
215+ if ((num < r -> start ) || ((num - r -> start ) % r -> step ))
216+ return 0 ;
217+ if (num >= (r -> start + (r -> len * r -> step )))
218+ return 0 ;
219+ }
220+ else {
221+ if ((num > r -> start ) || ((num - r -> start ) % r -> step ))
222+ return 0 ;
223+ if (num <= (r -> start + (r -> len * r -> step )))
224+ return 0 ;
225+ }
200226 return 1 ;
201227}
202228
203229static PySequenceMethods range_as_sequence = {
204- (inquiry )range_length , /*sq_length*/
230+ (inquiry )range_length , /*sq_length*/
205231 (binaryfunc )range_concat , /*sq_concat*/
206232 (intargfunc )range_repeat , /*sq_repeat*/
207233 (intargfunc )range_item , /*sq_item*/
208234 (intintargfunc )range_slice , /*sq_slice*/
209- 0 , /*sq_ass_item*/
210- 0 , /*sq_ass_slice*/
235+ 0 , /*sq_ass_item*/
236+ 0 , /*sq_ass_slice*/
211237 (objobjproc )range_contains , /*sq_contains*/
212238};
213239
0 commit comments