From 620e4b93eaa07b993662a40615db6e964abb4025 Mon Sep 17 00:00:00 2001 From: ugaemi Date: Sun, 26 Jul 2020 23:28:33 +0900 Subject: [PATCH 1/6] Add __ne__ for array, bytearray --- tests/snippets/bytearray.py | 7 +++++++ tests/snippets/stdlib_array.py | 7 +++++++ vm/src/bytesinner.rs | 4 ++++ vm/src/obj/objbytearray.rs | 5 +++++ vm/src/stdlib/array.rs | 19 +++++++++++++++++++ 5 files changed, 42 insertions(+) diff --git a/tests/snippets/bytearray.py b/tests/snippets/bytearray.py index 02331a598..31c2ae68b 100644 --- a/tests/snippets/bytearray.py +++ b/tests/snippets/bytearray.py @@ -713,3 +713,10 @@ assert a == bytearray(b'test') # mod assert bytearray('rust%bpython%b', 'utf-8') % (b' ', b'!') == bytearray(b'rust python!') assert bytearray('x=%i y=%f', 'utf-8') % (1, 2.5) == bytearray(b'x=1 y=2.500000') + +# eq, ne +a = bytearray(b'hello, world') +b = a.copy() +assert a.__ne__(b) is False +b = bytearray(b'my bytearray') +assert a.__ne__(b) is True diff --git a/tests/snippets/stdlib_array.py b/tests/snippets/stdlib_array.py index fb3a87ee1..0886b22c3 100644 --- a/tests/snippets/stdlib_array.py +++ b/tests/snippets/stdlib_array.py @@ -13,3 +13,10 @@ assert a1 == array("B", [3, 2, 1, 0]) a1.extend([4, 5, 6, 7]) assert a1 == array("h", [3, 2, 1, 0, 4, 5, 6, 7]) + +# eq, ne +a = array("b", [0, 1, 2, 3]) +b = a.copy() +assert a.__ne__(b) is False +b = array("B", [3, 2, 1, 0]) +assert a.__ne__(b) is True \ No newline at end of file diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index 3d10d153c..b0177ea62 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -274,6 +274,10 @@ impl PyBytesInner { self.cmp(other, |a, b| a == b, vm) } + pub fn ne(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyComparisonValue { + self.cmp(other, |a, b| a != b, vm) + } + pub fn ge(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyComparisonValue { self.cmp(other, |a, b| a >= b, vm) } diff --git a/vm/src/obj/objbytearray.rs b/vm/src/obj/objbytearray.rs index e8f439783..6d2ac48da 100644 --- a/vm/src/obj/objbytearray.rs +++ b/vm/src/obj/objbytearray.rs @@ -123,6 +123,11 @@ impl PyByteArray { self.borrow_value().eq(other, vm) } + #[pymethod(name = "__ne__")] + fn ne(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyComparisonValue { + self.borrow_value().ne(other, vm) + } + #[pymethod(name = "__ge__")] fn ge(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyComparisonValue { self.borrow_value().ge(other, vm) diff --git a/vm/src/stdlib/array.rs b/vm/src/stdlib/array.rs index 5161f1779..dda45292d 100644 --- a/vm/src/stdlib/array.rs +++ b/vm/src/stdlib/array.rs @@ -456,6 +456,25 @@ impl PyArray { } } + #[pymethod(name = "__ne__")] + fn ne(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { + let lhs = class_or_notimplemented!(vm, Self, lhs); + let rhs = class_or_notimplemented!(vm, Self, rhs); + let lhs = lhs.borrow_value(); + let rhs = rhs.borrow_value(); + if lhs.len() != rhs.len() { + Ok(vm.new_bool(true)) + } else { + for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { + let ne = objbool::boolval(vm, vm._ne(a?, b?)?)?; + if ne { + return Ok(vm.new_bool(true)); + } + } + Ok(vm.new_bool(false)) + } + } + #[pymethod(name = "__lt__")] fn lt(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { let lhs = class_or_notimplemented!(vm, Self, lhs); From 148e6cc5bc8b217991742f3d8698f045f3370e86 Mon Sep 17 00:00:00 2001 From: ugaemi Date: Sun, 16 Aug 2020 01:49:01 +0900 Subject: [PATCH 2/6] Fix ne for objbyteinner --- vm/src/bytesinner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index b0177ea62..72d260765 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -275,7 +275,7 @@ impl PyBytesInner { } pub fn ne(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyComparisonValue { - self.cmp(other, |a, b| a != b, vm) + self.eq(other, vm).map(|v| !v) } pub fn ge(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyComparisonValue { From 6abb67398d9f7979e7829284ac8c7528d284a08d Mon Sep 17 00:00:00 2001 From: ugaemi Date: Sun, 16 Aug 2020 01:50:52 +0900 Subject: [PATCH 3/6] Modify return type --- vm/src/macros.rs | 2 +- vm/src/stdlib/array.rs | 79 ++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/vm/src/macros.rs b/vm/src/macros.rs index 30abae114..def8505b8 100644 --- a/vm/src/macros.rs +++ b/vm/src/macros.rs @@ -221,7 +221,7 @@ macro_rules! class_or_notimplemented { ($vm:expr, $t:ty, $obj:expr) => { match $crate::pyobject::PyObject::downcast::<$t>($obj) { Ok(pyref) => pyref, - Err(_) => return Ok($vm.ctx.not_implemented()), + Err(_) => return Ok(PyArithmaticValue::NotImplemented), } }; } diff --git a/vm/src/stdlib/array.rs b/vm/src/stdlib/array.rs index dda45292d..2ff1e45eb 100644 --- a/vm/src/stdlib/array.rs +++ b/vm/src/stdlib/array.rs @@ -5,8 +5,8 @@ use crate::obj::objstr::PyStringRef; use crate::obj::objtype::PyClassRef; use crate::obj::{objbool, objiter}; use crate::pyobject::{ - BorrowValue, Either, IntoPyObject, PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, - PyValue, TryFromObject, + Either, IntoPyObject, PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, + TryFromObject, PyComparisonValue, PyArithmaticValue, }; use crate::VirtualMachine; @@ -438,113 +438,94 @@ impl PyArray { } #[pymethod(name = "__eq__")] - fn eq(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let lhs = class_or_notimplemented!(vm, Self, lhs); - let rhs = class_or_notimplemented!(vm, Self, rhs); - let lhs = lhs.borrow_value(); + fn eq(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + let lhs = self.borrow_value(); + let rhs = class_or_notimplemented!(vm, Self, other); let rhs = rhs.borrow_value(); if lhs.len() != rhs.len() { - Ok(vm.ctx.new_bool(false)) + Ok(PyArithmaticValue::Implemented(false)) } else { for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { let ne = objbool::boolval(vm, vm._ne(a, b)?)?; if ne { - return Ok(vm.ctx.new_bool(false)); + return Ok(PyArithmaticValue::Implemented(false)) } } - Ok(vm.ctx.new_bool(true)) + Ok(PyArithmaticValue::Implemented(true)) } } #[pymethod(name = "__ne__")] - fn ne(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let lhs = class_or_notimplemented!(vm, Self, lhs); - let rhs = class_or_notimplemented!(vm, Self, rhs); - let lhs = lhs.borrow_value(); - let rhs = rhs.borrow_value(); - if lhs.len() != rhs.len() { - Ok(vm.new_bool(true)) - } else { - for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { - let ne = objbool::boolval(vm, vm._ne(a?, b?)?)?; - if ne { - return Ok(vm.new_bool(true)); - } - } - Ok(vm.new_bool(false)) - } + fn ne(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + Ok(self.eq(other, vm)?.map(|v| !v)) } #[pymethod(name = "__lt__")] - fn lt(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let lhs = class_or_notimplemented!(vm, Self, lhs); - let rhs = class_or_notimplemented!(vm, Self, rhs); - let lhs = lhs.borrow_value(); + fn lt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + let lhs = self.borrow_value(); + let rhs = class_or_notimplemented!(vm, Self, other); let rhs = rhs.borrow_value(); for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { let lt = objbool::boolval(vm, vm._lt(a, b)?)?; if lt { - return Ok(vm.ctx.new_bool(true)); + return Ok(PyArithmaticValue::Implemented(true)); } } - Ok(vm.ctx.new_bool(lhs.len() < rhs.len())) + Ok(PyArithmaticValue::Implemented(lhs.len() < rhs.len())) } #[pymethod(name = "__le__")] - fn le(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let lhs = class_or_notimplemented!(vm, Self, lhs); - let rhs = class_or_notimplemented!(vm, Self, rhs); - let lhs = lhs.borrow_value(); + fn le(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + let lhs = self.borrow_value(); + let rhs = class_or_notimplemented!(vm, Self, other); let rhs = rhs.borrow_value(); for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { let le = objbool::boolval(vm, vm._le(a, b)?)?; if le { - return Ok(vm.ctx.new_bool(true)); + return Ok(PyArithmaticValue::Implemented(true)); } } - Ok(vm.ctx.new_bool(lhs.len() <= rhs.len())) + Ok(PyArithmaticValue::Implemented(lhs.len() <= rhs.len())) } #[pymethod(name = "__gt__")] - fn gt(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let lhs = class_or_notimplemented!(vm, Self, lhs); - let rhs = class_or_notimplemented!(vm, Self, rhs); - let lhs = lhs.borrow_value(); + fn gt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + let lhs = self.borrow_value(); + let rhs = class_or_notimplemented!(vm, Self, other); let rhs = rhs.borrow_value(); for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { let gt = objbool::boolval(vm, vm._gt(a, b)?)?; if gt { - return Ok(vm.ctx.new_bool(true)); + return Ok(PyArithmaticValue::Implemented(true)); } } - Ok(vm.ctx.new_bool(lhs.len() > rhs.len())) + Ok(PyArithmaticValue::Implemented(lhs.len() > rhs.len())) } #[pymethod(name = "__ge__")] - fn ge(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let lhs = class_or_notimplemented!(vm, Self, lhs); - let rhs = class_or_notimplemented!(vm, Self, rhs); - let lhs = lhs.borrow_value(); + fn ge(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + let lhs = self.borrow_value(); + let rhs = class_or_notimplemented!(vm, Self, other); let rhs = rhs.borrow_value(); for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { let ge = objbool::boolval(vm, vm._ge(a, b)?)?; if ge { - return Ok(vm.ctx.new_bool(true)); + return Ok(PyArithmaticValue::Implemented(true)); } } - Ok(vm.ctx.new_bool(lhs.len() >= rhs.len())) + Ok(PyArithmaticValue::Implemented(lhs.len() >= rhs.len())) } #[pymethod(name = "__len__")] From 32584a6c633a2a64cf4f75c1461ab56389415253 Mon Sep 17 00:00:00 2001 From: ugaemi Date: Sun, 16 Aug 2020 01:51:24 +0900 Subject: [PATCH 4/6] Fix test bug --- tests/snippets/stdlib_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/snippets/stdlib_array.py b/tests/snippets/stdlib_array.py index 0886b22c3..0ef0969ff 100644 --- a/tests/snippets/stdlib_array.py +++ b/tests/snippets/stdlib_array.py @@ -16,7 +16,7 @@ assert a1 == array("h", [3, 2, 1, 0, 4, 5, 6, 7]) # eq, ne a = array("b", [0, 1, 2, 3]) -b = a.copy() +b = a assert a.__ne__(b) is False b = array("B", [3, 2, 1, 0]) assert a.__ne__(b) is True \ No newline at end of file From b1eb20275d0a21a64c360dfb8492f486178cf063 Mon Sep 17 00:00:00 2001 From: ugaemi Date: Sun, 16 Aug 2020 03:19:12 +0900 Subject: [PATCH 5/6] Add crate BorrowValue --- vm/src/stdlib/array.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/src/stdlib/array.rs b/vm/src/stdlib/array.rs index 2ff1e45eb..7a5a6edb0 100644 --- a/vm/src/stdlib/array.rs +++ b/vm/src/stdlib/array.rs @@ -5,8 +5,8 @@ use crate::obj::objstr::PyStringRef; use crate::obj::objtype::PyClassRef; use crate::obj::{objbool, objiter}; use crate::pyobject::{ - Either, IntoPyObject, PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, - TryFromObject, PyComparisonValue, PyArithmaticValue, + BorrowValue, Either, IntoPyObject, PyArithmaticValue, PyClassImpl, PyComparisonValue, PyIterable, + PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, }; use crate::VirtualMachine; @@ -448,7 +448,7 @@ impl PyArray { for (a, b) in lhs.iter(vm).zip(rhs.iter(vm)) { let ne = objbool::boolval(vm, vm._ne(a, b)?)?; if ne { - return Ok(PyArithmaticValue::Implemented(false)) + return Ok(PyArithmaticValue::Implemented(false)); } } Ok(PyArithmaticValue::Implemented(true)) From 1d554eb065d889ea77060d3359ef320104afad4c Mon Sep 17 00:00:00 2001 From: ugaemi Date: Sun, 16 Aug 2020 03:25:37 +0900 Subject: [PATCH 6/6] Fix fmt --- vm/src/stdlib/array.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/src/stdlib/array.rs b/vm/src/stdlib/array.rs index 7a5a6edb0..5c5877cba 100644 --- a/vm/src/stdlib/array.rs +++ b/vm/src/stdlib/array.rs @@ -5,8 +5,8 @@ use crate::obj::objstr::PyStringRef; use crate::obj::objtype::PyClassRef; use crate::obj::{objbool, objiter}; use crate::pyobject::{ - BorrowValue, Either, IntoPyObject, PyArithmaticValue, PyClassImpl, PyComparisonValue, PyIterable, - PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, + BorrowValue, Either, IntoPyObject, PyArithmaticValue, PyClassImpl, PyComparisonValue, + PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, }; use crate::VirtualMachine;