Skip to content

Commit 8f3b62b

Browse files
authored
Merge pull request RustPython#895 from youknowone/pyrange-extend
extend_class for PyRange
2 parents fc729fd + 3051702 commit 8f3b62b

File tree

1 file changed

+39
-39
lines changed

1 file changed

+39
-39
lines changed

vm/src/obj/objrange.rs

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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,40 +105,15 @@ 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-
});
126-
108+
PyRange::extend_class(context, &context.range_type);
127109
PyRangeIterator::extend_class(context, &context.rangeiterator_type);
128110
}
129111

130112
type PyRangeRef = PyRef<PyRange>;
131113

114+
#[pyimpl]
132115
impl PyRange {
116+
#[pymethod(name = "__new__")]
133117
fn new(cls: PyClassRef, stop: PyIntRef, vm: &VirtualMachine) -> PyResult<PyRangeRef> {
134118
PyRange {
135119
start: PyInt::new(BigInt::zero()).into_ref(vm),
@@ -156,25 +140,30 @@ impl PyRange {
156140
.into_ref_with_type(vm, cls)
157141
}
158142

143+
#[pyproperty(name = "start")]
159144
fn start(&self, _vm: &VirtualMachine) -> PyIntRef {
160145
self.start.clone()
161146
}
162147

148+
#[pyproperty(name = "stop")]
163149
fn stop(&self, _vm: &VirtualMachine) -> PyIntRef {
164150
self.stop.clone()
165151
}
166152

153+
#[pyproperty(name = "step")]
167154
fn step(&self, _vm: &VirtualMachine) -> PyIntRef {
168155
self.step.clone()
169156
}
170157

158+
#[pymethod(name = "__iter__")]
171159
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRangeIterator {
172160
PyRangeIterator {
173161
position: Cell::new(0),
174162
range: zelf,
175163
}
176164
}
177165

166+
#[pymethod(name = "__reversed__")]
178167
fn reversed(&self, vm: &VirtualMachine) -> PyRangeIterator {
179168
let start = self.start.as_bigint();
180169
let stop = self.stop.as_bigint();
@@ -207,6 +196,7 @@ impl PyRange {
207196
}
208197
}
209198

199+
#[pymethod(name = "__len__")]
210200
fn len(&self, _vm: &VirtualMachine) -> PyInt {
211201
let start = self.start.as_bigint();
212202
let stop = self.stop.as_bigint();
@@ -220,6 +210,7 @@ impl PyRange {
220210
}
221211
}
222212

213+
#[pymethod(name = "__repr__")]
223214
fn repr(&self, _vm: &VirtualMachine) -> String {
224215
if self.step.as_bigint().is_one() {
225216
format!("range({}, {})", self.start, self.stop)
@@ -228,10 +219,12 @@ impl PyRange {
228219
}
229220
}
230221

222+
#[pymethod(name = "__bool__")]
231223
fn bool(&self, _vm: &VirtualMachine) -> bool {
232224
!self.is_empty()
233225
}
234226

227+
#[pymethod(name = "__contains__")]
235228
fn contains(&self, needle: PyObjectRef, _vm: &VirtualMachine) -> bool {
236229
if let Ok(int) = needle.downcast::<PyInt>() {
237230
match self.offset(int.as_bigint()) {
@@ -243,6 +236,7 @@ impl PyRange {
243236
}
244237
}
245238

239+
#[pymethod(name = "__eq__")]
246240
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> bool {
247241
if objtype::isinstance(&rhs, &vm.ctx.range_type()) {
248242
let rhs = get_value(&rhs);
@@ -254,6 +248,7 @@ impl PyRange {
254248
}
255249
}
256250

251+
#[pymethod(name = "index")]
257252
fn index(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyInt> {
258253
if let Ok(int) = needle.downcast::<PyInt>() {
259254
match self.index_of(int.as_bigint()) {
@@ -265,6 +260,7 @@ impl PyRange {
265260
}
266261
}
267262

263+
#[pymethod(name = "count")]
268264
fn count(&self, item: PyObjectRef, _vm: &VirtualMachine) -> PyInt {
269265
if let Ok(int) = item.downcast::<PyInt>() {
270266
if self.index_of(int.as_bigint()).is_some() {
@@ -277,6 +273,7 @@ impl PyRange {
277273
}
278274
}
279275

276+
#[pymethod(name = "__getitem__")]
280277
fn getitem(&self, subscript: RangeIndex, vm: &VirtualMachine) -> PyResult {
281278
match subscript {
282279
RangeIndex::Int(index) => {
@@ -323,18 +320,19 @@ impl PyRange {
323320
}
324321
}
325322
}
326-
}
327323

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+
}?;
336333

337-
Ok(range.into_object())
334+
Ok(range.into_object())
335+
}
338336
}
339337

340338
#[pyclass]
@@ -350,6 +348,8 @@ impl PyValue for PyRangeIterator {
350348
}
351349
}
352350

351+
type PyRangeIteratorRef = PyRef<PyRangeIterator>;
352+
353353
#[pyimpl]
354354
impl PyRangeIterator {
355355
#[pymethod(name = "__next__")]
@@ -364,7 +364,7 @@ impl PyRangeIterator {
364364
}
365365

366366
#[pymethod(name = "__iter__")]
367-
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
367+
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRangeIteratorRef {
368368
zelf
369369
}
370370
}

0 commit comments

Comments
 (0)