Skip to content

Commit 599f1f6

Browse files
committed
extend_class for PyRange
1 parent 132d34f commit 599f1f6

File tree

1 file changed

+36
-38
lines changed

1 file changed

+36
-38
lines changed

vm/src/obj/objrange.rs

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use num_traits::{One, Signed, Zero};
66

77
use crate::function::{OptionalArg, PyFuncArgs};
88
use crate::pyobject::{
9-
PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
9+
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
1010
};
1111
use crate::vm::VirtualMachine;
1212

@@ -15,6 +15,15 @@ use super::objiter;
1515
use super::objslice::{PySlice, PySliceRef};
1616
use super::objtype::{self, PyClassRef};
1717

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]
1827
#[derive(Debug, Clone)]
1928
pub struct PyRange {
2029
pub start: PyIntRef,
@@ -96,33 +105,7 @@ pub fn get_value(obj: &PyObjectRef) -> PyRange {
96105
}
97106

98107
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-
});
108+
PyRange::extend_class(context, &context.range_type);
126109

127110
let rangeiterator_type = &context.rangeiterator_type;
128111
extend_class!(context, rangeiterator_type, {
@@ -133,6 +116,7 @@ pub fn init(context: &PyContext) {
133116

134117
type PyRangeRef = PyRef<PyRange>;
135118

119+
#[pyimpl]
136120
impl PyRange {
137121
fn new(cls: PyClassRef, stop: PyIntRef, vm: &VirtualMachine) -> PyResult<PyRangeRef> {
138122
PyRange {
@@ -160,25 +144,30 @@ impl PyRange {
160144
.into_ref_with_type(vm, cls)
161145
}
162146

147+
#[pyproperty(name = "start")]
163148
fn start(&self, _vm: &VirtualMachine) -> PyIntRef {
164149
self.start.clone()
165150
}
166151

152+
#[pyproperty(name = "stop")]
167153
fn stop(&self, _vm: &VirtualMachine) -> PyIntRef {
168154
self.stop.clone()
169155
}
170156

157+
#[pyproperty(name = "step")]
171158
fn step(&self, _vm: &VirtualMachine) -> PyIntRef {
172159
self.step.clone()
173160
}
174161

162+
#[pymethod(name = "__iter__")]
175163
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRangeIterator {
176164
PyRangeIterator {
177165
position: Cell::new(0),
178166
range: zelf,
179167
}
180168
}
181169

170+
#[pymethod(name = "__reversed__")]
182171
fn reversed(&self, vm: &VirtualMachine) -> PyRangeIterator {
183172
let start = self.start.as_bigint();
184173
let stop = self.stop.as_bigint();
@@ -211,6 +200,7 @@ impl PyRange {
211200
}
212201
}
213202

203+
#[pymethod(name = "__len__")]
214204
fn len(&self, _vm: &VirtualMachine) -> PyInt {
215205
let start = self.start.as_bigint();
216206
let stop = self.stop.as_bigint();
@@ -224,6 +214,7 @@ impl PyRange {
224214
}
225215
}
226216

217+
#[pymethod(name = "__repr__")]
227218
fn repr(&self, _vm: &VirtualMachine) -> String {
228219
if self.step.as_bigint().is_one() {
229220
format!("range({}, {})", self.start, self.stop)
@@ -232,10 +223,12 @@ impl PyRange {
232223
}
233224
}
234225

226+
#[pymethod(name = "__bool__")]
235227
fn bool(&self, _vm: &VirtualMachine) -> bool {
236228
!self.is_empty()
237229
}
238230

231+
#[pymethod(name = "__contains__")]
239232
fn contains(&self, needle: PyObjectRef, _vm: &VirtualMachine) -> bool {
240233
if let Ok(int) = needle.downcast::<PyInt>() {
241234
match self.offset(int.as_bigint()) {
@@ -247,6 +240,7 @@ impl PyRange {
247240
}
248241
}
249242

243+
#[pymethod(name = "__eq__")]
250244
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> bool {
251245
if objtype::isinstance(&rhs, &vm.ctx.range_type()) {
252246
let rhs = get_value(&rhs);
@@ -258,6 +252,7 @@ impl PyRange {
258252
}
259253
}
260254

255+
#[pymethod(name = "index")]
261256
fn index(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyInt> {
262257
if let Ok(int) = needle.downcast::<PyInt>() {
263258
match self.index_of(int.as_bigint()) {
@@ -269,6 +264,7 @@ impl PyRange {
269264
}
270265
}
271266

267+
#[pymethod(name = "count")]
272268
fn count(&self, item: PyObjectRef, _vm: &VirtualMachine) -> PyInt {
273269
if let Ok(int) = item.downcast::<PyInt>() {
274270
if self.index_of(int.as_bigint()).is_some() {
@@ -281,6 +277,7 @@ impl PyRange {
281277
}
282278
}
283279

280+
#[pymethod(name = "__getitem__")]
284281
fn getitem(&self, subscript: RangeIndex, vm: &VirtualMachine) -> PyResult {
285282
match subscript {
286283
RangeIndex::Int(index) => {
@@ -327,18 +324,19 @@ impl PyRange {
327324
}
328325
}
329326
}
330-
}
331327

332-
fn range_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
333-
let range = if args.args.len() <= 2 {
334-
let (cls, stop) = args.bind(vm)?;
335-
PyRange::new(cls, stop, vm)
336-
} else {
337-
let (cls, start, stop, step) = args.bind(vm)?;
338-
PyRange::new_from(cls, start, stop, step, vm)
339-
}?;
328+
#[pymethod(name = "__new__")]
329+
fn range_new(args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
330+
let range = if args.args.len() <= 2 {
331+
let (cls, stop) = args.bind(vm)?;
332+
PyRange::new(cls, stop, vm)
333+
} else {
334+
let (cls, start, stop, step) = args.bind(vm)?;
335+
PyRange::new_from(cls, start, stop, step, vm)
336+
}?;
340337

341-
Ok(range.into_object())
338+
Ok(range.into_object())
339+
}
342340
}
343341

344342
#[derive(Debug)]

0 commit comments

Comments
 (0)