Skip to content

Commit 72b4965

Browse files
authored
Merge pull request #1497 from HyeockJinKim/ne
Add __ne__ methods
2 parents 6f9aeb0 + 37e85df commit 72b4965

File tree

6 files changed

+122
-29
lines changed

6 files changed

+122
-29
lines changed

tests/snippets/builtin_range.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@
5858
assert range(0, 10, 3) == range(0, 12, 3)
5959
assert range(20, 10, 3) == range(20, 12, 3)
6060

61+
assert range(10).__eq__(range(0, 10, 1)) is True
62+
assert range(10).__ne__(range(0, 10, 1)) is False
63+
assert range(10).__eq__(range(0, 11, 1)) is False
64+
assert range(10).__ne__(range(0, 11, 1)) is True
65+
assert range(0, 10, 3).__eq__(range(0, 11, 3)) is True
66+
assert range(0, 10, 3).__ne__(range(0, 11, 3)) is False
6167
#__lt__
6268
assert range(1, 2, 3).__lt__(range(1, 2, 3)) == NotImplemented
6369
assert range(1, 2, 1).__lt__(range(1, 2)) == NotImplemented

tests/snippets/floats.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,34 @@
229229
# Test float exponent:
230230
assert 1 if 1else 0 == 1
231231

232+
a = 3.
233+
assert a.__eq__(3) is True
234+
assert a.__eq__(3.) is True
235+
assert a.__eq__(3.00000) is True
236+
assert a.__eq__(3.01) is False
237+
238+
pi = 3.14
239+
assert pi.__eq__(3.14) is True
240+
assert pi.__ne__(3.14) is False
241+
assert pi.__eq__(3) is False
242+
assert pi.__ne__(3) is True
243+
assert pi.__eq__('pi') is NotImplemented
244+
assert pi.__ne__('pi') is NotImplemented
245+
246+
assert pi.__eq__(float('inf')) is False
247+
assert pi.__ne__(float('inf')) is True
248+
assert float('inf').__eq__(pi) is False
249+
assert float('inf').__ne__(pi) is True
250+
assert float('inf').__eq__(float('inf')) is True
251+
assert float('inf').__ne__(float('inf')) is False
252+
assert float('inf').__eq__(float('nan')) is False
253+
assert float('inf').__ne__(float('nan')) is True
254+
255+
assert pi.__eq__(float('nan')) is False
256+
assert pi.__ne__(float('nan')) is True
257+
assert float('nan').__eq__(pi) is False
258+
assert float('nan').__ne__(pi) is True
259+
assert float('nan').__eq__(float('nan')) is False
260+
assert float('nan').__ne__(float('nan')) is True
261+
assert float('nan').__eq__(float('inf')) is False
262+
assert float('nan').__ne__(float('inf')) is True

tests/snippets/none.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ def none2():
1818
assert str(None) == 'None'
1919
assert repr(None) == 'None'
2020
assert type(None)() is None
21+
22+
assert None.__eq__(3) is NotImplemented
23+
assert None.__ne__(3) is NotImplemented
24+
assert None.__eq__(None) is True
25+
assert None.__ne__(None) is False
26+

vm/src/obj/objfloat.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,20 +179,39 @@ impl PyFloat {
179179
PyFloat::from(float_val?).into_ref_with_type(vm, cls)
180180
}
181181

182+
fn float_eq(&self, other: PyObjectRef) -> bool {
183+
let other = get_value(&other);
184+
self.value == other
185+
}
186+
187+
fn int_eq(&self, other: PyObjectRef) -> bool {
188+
let other_int = objint::get_value(&other);
189+
let value = self.value;
190+
if let (Some(self_int), Some(other_float)) = (value.to_bigint(), other_int.to_f64()) {
191+
value == other_float && self_int == *other_int
192+
} else {
193+
false
194+
}
195+
}
196+
182197
#[pymethod(name = "__eq__")]
183198
fn eq(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
184-
let value = self.value;
185199
let result = if objtype::isinstance(&other, &vm.ctx.float_type()) {
186-
let other = get_value(&other);
187-
value == other
200+
self.float_eq(other)
188201
} else if objtype::isinstance(&other, &vm.ctx.int_type()) {
189-
let other_int = objint::get_value(&other);
202+
self.int_eq(other)
203+
} else {
204+
return vm.ctx.not_implemented();
205+
};
206+
vm.ctx.new_bool(result)
207+
}
190208

191-
if let (Some(self_int), Some(other_float)) = (value.to_bigint(), other_int.to_f64()) {
192-
value == other_float && self_int == *other_int
193-
} else {
194-
false
195-
}
209+
#[pymethod(name = "__ne__")]
210+
fn ne(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
211+
let result = if objtype::isinstance(&other, &vm.ctx.float_type()) {
212+
!self.float_eq(other)
213+
} else if objtype::isinstance(&other, &vm.ctx.int_type()) {
214+
!self.int_eq(other)
196215
} else {
197216
return vm.ctx.not_implemented();
198217
};

vm/src/obj/objnone.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ impl PyNoneRef {
111111
Err(vm.new_attribute_error(format!("{} has no attribute '{}'", self.as_object(), name)))
112112
}
113113
}
114+
115+
#[pymethod(name = "__eq__")]
116+
fn eq(self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
117+
if vm.is_none(&rhs) {
118+
vm.ctx.new_bool(true)
119+
} else {
120+
vm.ctx.not_implemented()
121+
}
122+
}
123+
124+
#[pymethod(name = "__ne__")]
125+
fn ne(self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
126+
if vm.is_none(&rhs) {
127+
vm.ctx.new_bool(false)
128+
} else {
129+
vm.ctx.not_implemented()
130+
}
131+
}
114132
}
115133

116134
pub fn init(context: &PyContext) {

vm/src/obj/objrange.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::vm::VirtualMachine;
1414
use super::objint::{PyInt, PyIntRef};
1515
use super::objiter;
1616
use super::objslice::{PySlice, PySliceRef};
17-
use super::objtype::{self, PyClassRef};
17+
use super::objtype::PyClassRef;
1818

1919
/// range(stop) -> range object
2020
/// range(start, stop[, step]) -> range object
@@ -239,30 +239,43 @@ impl PyRange {
239239
}
240240
}
241241

242-
#[pymethod(name = "__eq__")]
243-
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> bool {
244-
if objtype::isinstance(&rhs, &vm.ctx.range_type()) {
245-
let rhs = get_value(&rhs);
242+
fn inner_eq(&self, rhs: &PyRange) -> bool {
243+
if self.length() != rhs.length() {
244+
return false;
245+
}
246246

247-
if self.length() != rhs.length() {
248-
return false;
249-
}
247+
if self.length().is_zero() {
248+
return true;
249+
}
250250

251-
if self.length().is_zero() {
252-
return true;
253-
}
251+
if self.start.as_bigint() != rhs.start.as_bigint() {
252+
return false;
253+
}
254+
let step = self.step.as_bigint();
255+
if step.is_one() || step == rhs.step.as_bigint() {
256+
return true;
257+
}
254258

255-
if self.start.as_bigint() != rhs.start.as_bigint() {
256-
return false;
257-
}
258-
let step = self.step.as_bigint();
259-
if step.is_one() || step == rhs.step.as_bigint() {
260-
return true;
261-
}
259+
false
260+
}
262261

263-
false
262+
#[pymethod(name = "__eq__")]
263+
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
264+
if let Some(rhs) = rhs.payload::<PyRange>() {
265+
let eq = self.inner_eq(rhs);
266+
Ok(vm.ctx.new_bool(eq))
264267
} else {
265-
false
268+
Ok(vm.ctx.not_implemented())
269+
}
270+
}
271+
272+
#[pymethod(name = "__ne__")]
273+
fn ne(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
274+
if let Some(rhs) = rhs.payload::<PyRange>() {
275+
let eq = self.inner_eq(rhs);
276+
Ok(vm.ctx.new_bool(!eq))
277+
} else {
278+
Ok(vm.ctx.not_implemented())
266279
}
267280
}
268281

0 commit comments

Comments
 (0)