8000 Refactor deque and fix comparison bug · RustPython/RustPython@f1ca0b4 · GitHub
[go: up one dir, main page]

Skip to content

Commit f1ca0b4

Browse files
committed
Refactor deque and fix comparison bug
1 parent db67018 commit f1ca0b4

File tree

2 files changed

+74
-66
lines changed

2 files changed

+74
-66
lines changed

tests/snippets/stdlib_collections.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,10 @@
3737
assert deque([1, 2, 3, 4], maxlen=2) == deque([3, 4])
3838

3939
assert len(deque([1, 2, 3, 4])) == 4
40+
41+
assert d >= d
42+
assert not (d > d)
43+
assert d <= d
44+
assert not (d < d)
45+
assert d == d
46+
assert not (d != d)

vm/src/stdlib/collections.rs

Lines changed: 67 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use crate::function::OptionalArg;
22
use crate::obj::{objiter, objtype::PyClassRef};
3-
use crate::pyobject::{IdProtocol, PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue};
3+
use crate::pyobject::{
4+
IdProtocol, PyArithmaticValue::*, PyClassImpl, PyComparisonValue, PyIterable, PyObjectRef,
5+
PyRef, PyResult, PyValue,
6+
};
47
use crate::sequence::{self, SimpleSeq};
58
use crate::vm::ReprGuard;
69
use crate::VirtualMachine;
@@ -29,7 +32,7 @@ struct PyDequeOptions {
2932
}
3033

3134
impl PyDeque {
32-
pub fn borrow_sequence<'a>(&'a self) -> impl SimpleSeq + 'a {
35+
pub fn borrow_deque<'a>(&'a self) -> impl std::ops::Deref<Target = VecDeque<PyObjectRef>> + 'a {
3336
self.deque.borrow()
3437
}
3538
}
@@ -208,6 +211,7 @@ impl PyDeque {
208211
fn maxlen(&self, _vm: &VirtualMachine) -> Option<usize> {
209212
self.maxlen.get()
210213
}
214+
211215
#[pyproperty(setter)]
212216
fn set_maxlen(&self, maxlen: Option<usize>, _vm: &VirtualMachine) {
213217
self.maxlen.set(maxlen);
@@ -234,94 +238,91 @@ impl PyDeque {
234238
Ok(repr)
235239
}
236240

241+
#[inline]
242+
fn cmp<F>(&self, other: PyObjectRef, op: F, vm: &VirtualMachine) -> PyResult<PyComparisonValue>
243+
where
244+
F: Fn(&VecDeque<PyObjectRef>, &VecDeque<PyObjectRef>) -> PyResult<bool>,
245+
{
246+
let r = if let Some(other) = other.payload_if_subclass::<PyDeque>(vm) {
247+
Implemented(op(&*self.borrow_deque(), &*other.borrow_deque())?)
248+
} else {
249+
NotImplemented
250+
};
251+
Ok(r)
252+
}
253+
237254
#[pymethod(name = "__eq__")]
238-
fn eq(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
255+
fn eq(
256+
zelf: PyRef<Self>,
257+
other: PyObjectRef,
258+
vm: &VirtualMachine,
259+
) -> PyResult<PyComparisonValue> {
239260
if zelf.as_object().is(&other) {
240-
return Ok(vm.new_bool(true));
261+
Ok(Implemented(true))
262+
} else {
263+
zelf.cmp(other, |a, b| sequence::eq(vm, a, b), vm)
241264
}
265+
}
242266

243-
let other = match_class!(match other {
244-
other @ Self => other,
245-
_ => return Ok(vm.ctx.not_implemented()),
246-
});
247-
248-
let lhs = &zelf.borrow_sequence();
249-
let rhs = &other.borrow_sequence();
250-
251-
let eq = sequence::eq(vm, lhs, rhs)?;
252-
Ok(vm.new_bool(eq))
267+
#[pymethod(name = "__ne__")]
268+
fn ne(
269+
zelf: PyRef<Self>,
270+
other: PyObjectRef,
271+
vm: &VirtualMachine,
272+
) -> PyResult<PyComparisonValue> {
273+
Ok(PyDeque::eq(zelf, other, vm)?.map(|v| !v))
253274
}
254275

255276
#[pymethod(name = "__lt__")]
256-
fn lt(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
277+
fn lt(
278+
zelf: PyRef<Self>,
279+
other: PyObjectRef,
280+
vm: &VirtualMachine,
281+
) -> PyResult<PyComparisonValue> {
257282
if zelf.as_object().is(&other) {
258-
return Ok(vm.new_bool(true));
283+
Ok(Implemented(false))
284+
} else {
285+
zelf.cmp(other, |a, b| sequence::lt(vm, a, b), vm)
259286
}
260-
261-
let other = match_class!(match other {
262-
other @ Self => other,
263-
_ => return Ok(vm.ctx.not_implemented()),
264-
});
265-
266-
let lhs = &zelf.borrow_sequence();
267-
let rhs = &other.borrow_sequence();
268-
269-
let eq = sequence::lt(vm, lhs, rhs)?;
270-
Ok(vm.new_bool(eq))
271287
}
272288

273289
#[pymethod(name = "__gt__")]
274-
fn gt(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
290+
fn gt(
291+
zelf: PyRef<Self>,
292+
other: PyObjectRef,
293+
vm: &VirtualMachine,
294+
) -> PyResult<PyComparisonValue> {
275295
if zelf.as_object().is(&other) {
276-
return Ok(vm.new_bool(true));
296+
Ok(Implemented(false))
297+
} else {
298+
zelf.cmp(other, |a, b| sequence::gt(vm, a, b), vm)
277299
}
278-
279-
let other = match_class!(match other {
280-
other @ Self => other,
281-
_ => return Ok(vm.ctx.not_implemented()),
282-
});
283-
284-
let lhs = &zelf.borrow_sequence();
285-
let rhs = &other.borrow_sequence();
286-
287-
let eq = sequence::gt(vm, lhs, rhs)?;
288-
Ok(vm.new_bool(eq))
289300
}
290301

291302
#[pymethod(name = "__le__")]
292-
fn le(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
303+
fn le(
304+
zelf: PyRef<Self>,
305+
other: PyObjectRef,
306+
vm: &VirtualMachine,
307+
) -> PyResult<PyComparisonValue> {
293308
if zelf.as_object().is(&other) {
294-
return Ok(vm.new_bool(true));
309+
Ok(Implemented(true))
310+
} else {
311+
zelf.cmp(other, |a, b| sequence::le(vm, a, b), vm)
295312
}
296-
297-
let other = match_class!(match other {
298-
other @ Self => other,
299-
_ => return Ok(vm.ctx.not_implemented()),
300-
});
301-
302-
let lhs = &zelf.borrow_sequence();
303-
let rhs = &other.borrow_sequence();
304-
305-
let eq = sequence::le(vm, lhs, rhs)?;
306-
Ok(vm.new_bool(eq))
307313
}
308314

309315
#[pymethod(name = "__ge__")]
310-
fn ge(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
316+
fn ge(
317+
zelf: PyRef<Self>,
318+
other: PyObjectRef,
319+
vm: &VirtualMachine,
320+
) -> PyResult<PyComparisonValue> {
311321
if zelf.as_object().is(&other) {
312-
return Ok(vm.new_bool(true));
322+
Ok(Implemented(true))
323+
} else {
324+
zelf.cmp(other, |a, b| sequence::ge(vm, a, b), vm)
313325
}
314-
315-
let other = match_class!(match other {
316-
other @ Self => other,
317-
_ => return Ok(vm.ctx.not_implemented()),
318-
});
319-
320-
let lhs = &zelf.borrow_sequence();
321-
let rhs = &other.borrow_sequence();
322-
323-
let eq = sequence::ge(vm, lhs, rhs)?;
324-
Ok(vm.new_bool(eq))
325326
}
326327

327328
#[pymethod(name = "__mul__")]

0 commit comments

Comments
 (0)
0