@@ -15,6 +15,15 @@ use super::objiter;
15
15
use super :: objslice:: { PySlice , PySliceRef } ;
16
16
use super :: objtype:: { self , PyClassRef } ;
17
17
18
+ /// range(stop) -> range object
19
+ /// range(start, stop[, step]) -> range object
20
+ ///
21
+ /// Return an object that produces a sequence of integers from start (inclusive)
22
+ /// to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
23
+ /// start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
24
+ /// These are exactly the valid indices for a list of 4 elements.
25
+ /// When step is given, it specifies the increment (or decrement).
26
+ #[ pyclass]
18
27
#[ derive( Debug , Clone ) ]
19
28
pub struct PyRange {
20
29
pub start : PyIntRef ,
@@ -96,40 +105,15 @@ pub fn get_value(obj: &PyObjectRef) -> PyRange {
96
105
}
97
106
98
107
pub fn init ( context : & PyContext ) {
99
- let range_type = & context. range_type ;
100
-
101
- let range_doc = "range(stop) -> range object\n \
102
- range(start, stop[, step]) -> range object\n \n \
103
- Return an object that produces a sequence of integers from start (inclusive)\n \
104
- to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n \
105
- start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n \
106
- These are exactly the valid indices for a list of 4 elements.\n \
107
- When step is given, it specifies the increment (or decrement).";
108
-
109
- extend_class ! ( context, range_type, {
110
- "__bool__" => context. new_rustfunc( PyRange :: bool ) ,
111
- "__contains__" => context. new_rustfunc( PyRange :: contains) ,
112
- "__doc__" => context. new_str( range_doc. to_string( ) ) ,
113
- "__eq__" => context. new_rustfunc( PyRange :: eq) ,
114
- "__getitem__" => context. new_rustfunc( PyRange :: getitem) ,
115
- "__iter__" => context. new_rustfunc( PyRange :: iter) ,
116
- "__len__" => context. new_rustfunc( PyRange :: len) ,
117
- "__new__" => context. new_rustfunc( range_new) ,
118
- "__repr__" => context. new_rustfunc( PyRange :: repr) ,
119
- "__reversed__" => context. new_rustfunc( PyRange :: reversed) ,
120
- "count" => context. new_rustfunc( PyRange :: count) ,
121
- "index" => context. new_rustfunc( PyRange :: index) ,
122
- "start" => context. new_property( PyRange :: start) ,
123
- "stop" => context. new_property( PyRange :: stop) ,
124
- "step" => context. new_property( PyRange :: step) ,
125
- } ) ;
126
-
108
+ PyRange :: extend_class ( context, & context. range_type ) ;
127
109
PyRangeIterator :: extend_class ( context, & context. rangeiterator_type ) ;
128
110
}
129
111
130
112
type PyRangeRef = PyRef < PyRange > ;
131
113
114
+ #[ pyimpl]
132
115
impl PyRange {
116
+ #[ pymethod( name = "__new__" ) ]
133
117
fn new ( cls : PyClassRef , stop : PyIntRef , vm : & VirtualMachine ) -> PyResult < PyRangeRef > {
134
118
PyRange {
135
119
start : PyInt :: new ( BigInt :: zero ( ) ) . into_ref ( vm) ,
@@ -156,25 +140,30 @@ impl PyRange {
156
140
. into_ref_with_type ( vm, cls)
157
141
}
158
142
143
+ #[ pyproperty( name = "start" ) ]
159
144
fn start ( & self , _vm : & VirtualMachine ) -> PyIntRef {
160
145
self . start . clone ( )
161
146
}
162
147
148
+ #[ pyproperty( name = "stop" ) ]
163
149
fn stop ( & self , _vm : & VirtualMachine ) -> PyIntRef {
164
150
self . stop . clone ( )
165
151
}
166
152
153
+ #[ pyproperty( name = "step" ) ]
167
154
fn step ( & self , _vm : & VirtualMachine ) -> PyIntRef {
168
155
self . step . clone ( )
169
156
}
170
157
158
+ #[ pymethod( name = "__iter__" ) ]
171
159
fn iter ( zelf : PyRef < Self > , _vm : & VirtualMachine ) -> PyRangeIterator {
172
160
PyRangeIterator {
173
161
position : Cell :: new ( 0 ) ,
174
162
range : zelf,
175
163
}
176
164
}
177
165
166
+ #[ pymethod( name = "__reversed__" ) ]
178
167
fn reversed ( & self , vm : & VirtualMachine ) -> PyRangeIterator {
179
168
let start = self . start . as_bigint ( ) ;
180
169
let stop = self . stop . as_bigint ( ) ;
@@ -207,6 +196,7 @@ impl PyRange {
207
196
}
208
197
}
209
198
199
+ #[ pymethod( name = "__len__" ) ]
210
200
fn len ( & self , _vm : & VirtualMachine ) -> PyInt {
211
201
let start = self . start . as_bigint ( ) ;
212
202
let stop = self . stop . as_bigint ( ) ;
@@ -220,6 +210,7 @@ impl PyRange {
220
210
}
221
211
}
222
212
213
+ #[ pymethod( name = "__repr__" ) ]
223
214
fn repr ( & self , _vm : & VirtualMachine ) -> String {
224
215
if self . step . as_bigint ( ) . is_one ( ) {
225
216
format ! ( "range({}, {})" , self . start, self . stop)
@@ -228,10 +219,12 @@ impl PyRange {
228
219
}
229
220
}
230
221
222
+ #[ pymethod( name = "__bool__" ) ]
231
223
fn bool ( & self , _vm : & VirtualMachine ) -> bool {
232
224
!self . is_empty ( )
233
225
}
234
226
227
+ #[ pymethod( name = "__contains__" ) ]
235
228
fn contains ( & self , needle : PyObjectRef , _vm : & VirtualMachine ) -> bool {
236
229
if let Ok ( int) = needle. downcast :: < PyInt > ( ) {
237
230
match self . offset ( int. as_bigint ( ) ) {
@@ -243,6 +236,7 @@ impl PyRange {
243
236
}
244
237
}
245
238
239
+ #[ pymethod( name = "__eq__" ) ]
246
240
fn eq ( & self , rhs : PyObjectRef , vm : & VirtualMachine ) -> bool {
247
241
if objtype:: isinstance ( & rhs, & vm. ctx . range_type ( ) ) {
248
242
let rhs = get_value ( & rhs) ;
@@ -254,6 +248,7 @@ impl PyRange {
254
248
}
255
249
}
256
250
251
+ #[ pymethod( name = "index" ) ]
257
252
fn index ( & self , needle : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyInt > {
258
253
if let Ok ( int) = needle. downcast :: < PyInt > ( ) {
259
254
match self . index_of ( int. as_bigint ( ) ) {
@@ -265,6 +260,7 @@ impl PyRange {
265
260
}
266
261
}
267
262
263
+ #[ pymethod( name = "count" ) ]
268
264
fn count ( & self , item : PyObjectRef , _vm : & VirtualMachine ) -> PyInt {
269
265
if let Ok ( int) = item. downcast :: < PyInt > ( ) {
270
266
if self . index_of ( int. as_bigint ( ) ) . is_some ( ) {
@@ -277,6 +273,7 @@ impl PyRange {
277
273
}
278
274
}
279
275
276
+ #[ pymethod( name = "__getitem__" ) ]
280
277
fn getitem ( & self , subscript : RangeIndex , vm : & VirtualMachine ) -> PyResult {
281
278
match subscript {
282
279
RangeIndex :: Int ( index) => {
@@ -323,18 +320,19 @@ impl PyRange {
323
320
}
324
321
}
325
322
}
326
- }
327
323
328
- fn range_new ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
329
- let range = if args. args . len ( ) <= 2 {
330
- let ( cls, stop) = args. bind ( vm) ?;
331
- PyRange :: new ( cls, stop, vm)
332
- } else {
333
- let ( cls, start, stop, step) = args. bind ( vm) ?;
334
- PyRange :: new_from ( cls, start, stop, step, vm)
335
- } ?;
324
+ #[ pymethod( name = "__new__" ) ]
325
+ fn range_new ( args : PyFuncArgs , vm : & VirtualMachine ) -> PyResult {
326
+ let range = if args. args . len ( ) <= 2 {
327
+ let ( cls, stop) = args. bind ( vm) ?;
328
+ PyRange :: new ( cls, stop, vm)
329
+ } else {
330
+ let ( cls, start, stop, step) = args. bind ( vm) ?;
331
+ PyRange :: new_from ( cls, start, stop, step, vm)
332
+ } ?;
336
333
337
- Ok ( range. into_object ( ) )
334
+ Ok ( range. into_object ( ) )
335
+ }
338
336
}
339
337
340
338
#[ pyclass]
@@ -350,6 +348,8 @@ impl PyValue for PyRangeIterator {
350
348
}
351
349
}
352
350
351
+ type PyRangeIteratorRef = PyRef < PyRangeIterator > ;
352
+
353
353
#[ pyimpl]
354
354
impl PyRangeIterator {
355
355
#[ pymethod( name = "__next__" ) ]
@@ -364,7 +364,7 @@ impl PyRangeIterator {
364
364
}
365
365
366
366
#[ pymethod( name = "__iter__" ) ]
367
- fn iter ( zelf : PyRef < Self > , _vm : & VirtualMachine ) -> PyRef < Self > {
367
+ fn iter ( zelf : PyRef < Self > , _vm : & VirtualMachine ) -> PyRangeIteratorRef {
368
368
zelf
369
369
}
370
370
}
0 commit comments