Skip to content

Commit 45f45bf

Browse files
authored
Merge pull request RustPython#433 from OddCoincidence/not-implemented
Use NotImplemented in binary operations
2 parents 5c378d3 + 057a225 commit 45f45bf

File tree

10 files changed

+114
-106
lines changed

10 files changed

+114
-106
lines changed

tests/snippets/builtin_complex.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88

99
assert complex(1, -1) == complex(1, -1)
1010
assert complex(1, 0) == 1
11-
assert not complex(1, 1) == 1
11+
assert 1 == complex(1, 0)
12+
assert complex(1, 1) != 1
13+
assert 1 != complex(1, 1)
1214
assert complex(1, 0) == 1.0
13-
assert not complex(1, 1) == 1.0
14-
assert not complex(1, 0) == 1.5
15+
assert 1.0 == complex(1, 0)
16+
assert complex(1, 1) != 1.0
17+
assert 1.0 != complex(1, 1)
18+
assert complex(1, 0) != 1.5
19+
assert not 1.0 != complex(1, 0)
1520
assert bool(complex(1, 0))
16-
assert not complex(1, 2) == complex(1, 1)
17-
# Currently broken - see issue #419
18-
# assert complex(1, 2) != 'foo'
21+
assert complex(1, 2) != complex(1, 1)
22+
assert complex(1, 2) != 'foo'
1923
assert complex(1, 2).__eq__('foo') == NotImplemented
2024

2125
# __neg__

tests/snippets/object.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class MyObject:
2+
pass
3+
4+
assert not MyObject() == MyObject()
5+
assert MyObject() != MyObject()
6+
myobj = MyObject()
7+
assert myobj == myobj
8+
assert not myobj != myobj
9+
10+
assert MyObject().__eq__(MyObject()) == NotImplemented
11+
assert MyObject().__ne__(MyObject()) == NotImplemented

vm/src/frame.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,8 @@ impl Frame {
988988
let b = self.pop_value();
989989
let a = self.pop_value();
990990
let value = match *op {
991-
bytecode::ComparisonOperator::Equal => vm._eq(&a, b)?,
992-
bytecode::ComparisonOperator::NotEqual => vm._ne(&a, b)?,
991+
bytecode::ComparisonOperator::Equal => vm._eq(a, b)?,
992+
bytecode::ComparisonOperator::NotEqual => vm._ne(a, b)?,
993993
bytecode::ComparisonOperator::Less => vm._lt(&a, b)?,
994994
bytecode::ComparisonOperator::LessOrEqual => vm._le(&a, b)?,
995995
bytecode::ComparisonOperator::Greater => vm._gt(&a, b)?,

vm/src/obj/objfloat.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ fn float_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
8080
false
8181
}
8282
} else {
83-
false
83+
return Ok(vm.ctx.not_implemented());
8484
};
8585
Ok(vm.ctx.new_bool(result))
8686
}
@@ -181,7 +181,7 @@ fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
181181
.ctx
182182
.new_float(v1 + objint::get_value(i2).to_f64().unwrap()))
183183
} else {
184-
Err(vm.new_type_error(format!("Cannot add {} and {}", i.borrow(), i2.borrow())))
184+
Ok(vm.ctx.not_implemented())
185185
}
186186
}
187187

@@ -198,11 +198,7 @@ fn float_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
198198
let r2 = float_mod(vm, args.clone())?;
199199
Ok(vm.ctx.new_tuple(vec![r1, r2]))
200200
} else {
201-
Err(vm.new_type_error(format!(
202-
"Cannot divmod power {} and {}",
203-
i.borrow(),
204-
i2.borrow()
205-
)))
201+
Ok(vm.ctx.not_implemented())
206202
}
207203
}
208204

@@ -221,11 +217,7 @@ fn float_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
221217
.to_f64()
222218
.ok_or_else(|| vm.new_overflow_error("int too large to convert to float".to_string()))?
223219
} else {
224-
return Err(vm.new_type_error(format!(
225-
"Cannot floordiv {} and {}",
226-
i.borrow(),
227-
i2.borrow()
228-
)));
220+
return Ok(vm.ctx.not_implemented());
229221
};
230222

231223
if v2 != 0.0 {
@@ -249,7 +241,7 @@ fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
249241
.ctx
250242
.new_float(v1 - objint::get_value(i2).to_f64().unwrap()))
251243
} else {
252-
Err(vm.new_type_error(format!("Cannot add {} and {}", i.borrow(), i2.borrow())))
244+
Ok(vm.ctx.not_implemented())
253245
}
254246
}
255247

@@ -268,7 +260,7 @@ fn float_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
268260
.to_f64()
269261
.ok_or_else(|| vm.new_overflow_error("int too large to convert to float".to_string()))?
270262
} else {
271-
return Err(vm.new_type_error(format!("Cannot mod {} and {}", i.borrow(), i2.borrow())));
263+
return Ok(vm.ctx.not_implemented());
272264
};
273265

274266
if v2 != 0.0 {
@@ -300,7 +292,7 @@ fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
300292
let result = v1.powf(objint::get_value(i2).to_f64().unwrap());
301293
Ok(vm.ctx.new_float(result))
302294
} else {
303-
Err(vm.new_type_error(format!("Cannot add {} and {}", i.borrow(), i2.borrow())))
295+
Ok(vm.ctx.not_implemented())
304296
}
305297
}
306298

vm/src/obj/objint.rs

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ fn int_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
125125
false
126126
}
127127
} else {
128-
false
128+
return Ok(vm.ctx.not_implemented());
129129
};
130130
Ok(vm.ctx.new_bool(result))
131131
}
@@ -303,11 +303,7 @@ fn int_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
303303
Err(vm.new_zero_division_error("integer floordiv by zero".to_string()))
304304
}
305305
} else {
306-
Err(vm.new_type_error(format!(
307-
"Cannot floordiv {} and {}",
308-
i.borrow(),
309-
i2.borrow()
310-
)))
306+
Ok(vm.ctx.not_implemented())
311307
}
312308
}
313309

@@ -358,11 +354,7 @@ fn int_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
358354
.ctx
359355
.new_float(i.to_f64().unwrap() - objfloat::get_value(i2)))
360356
} else {
361-
Err(vm.new_not_implemented_error(format!(
362-
"Cannot substract {} and {}",
363-
_i.borrow(),
364-
i2.borrow()
365-
)))
357+
Ok(vm.ctx.not_implemented())
366358
}
367359
}
368360

@@ -379,11 +371,7 @@ fn int_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
379371
.ctx
380372
.new_float(get_value(i).to_f64().unwrap() * objfloat::get_value(i2)))
381373
} else {
382-
Err(vm.new_type_error(format!(
383-
"Cannot multiply {} and {}",
384-
i.borrow(),
385-
i2.borrow()
386-
)))
374+
Ok(vm.ctx.not_implemented())
387375
}
388376
}
389377

@@ -405,7 +393,7 @@ fn int_truediv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
405393
} else if objtype::isinstance(i2, &vm.ctx.float_type()) {
406394
objfloat::get_value(i2)
407395
} else {
408-
return Err(vm.new_type_error(format!("Cannot divide {} and {}", i.borrow(), i2.borrow())));
396+
return Ok(vm.ctx.not_implemented());
409397
};
410398

411399
if v2 == 0.0 {
@@ -431,7 +419,7 @@ fn int_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
431419
Err(vm.new_zero_division_error("integer modulo by zero".to_string()))
432420
}
433421
} else {
434-
Err(vm.new_type_error(format!("Cannot modulo {} and {}", i.borrow(), i2.borrow())))
422+
Ok(vm.ctx.not_implemented())
435423
}
436424
}
437425

@@ -460,11 +448,7 @@ fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
460448
let v2 = objfloat::get_value(i2);
461449
Ok(vm.ctx.new_float((v1.to_f64().unwrap()).powf(v2)))
462450
} else {
463-
Err(vm.new_type_error(format!(
464-
"Cannot raise power {} and {}",
465-
i.borrow(),
466-
i2.borrow()
467-
)))
451+
Ok(vm.ctx.not_implemented())
468452
}
469453
}
470454

@@ -489,11 +473,7 @@ fn int_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
489473
Err(vm.new_zero_division_error("integer divmod by zero".to_string()))
490474
}
491475
} else {
492-
Err(vm.new_type_error(format!(
493-
"Cannot divmod power {} and {}",
494-
i.borrow(),
495-
i2.borrow()
496-
)))
476+
Ok(vm.ctx.not_implemented())
497477
}
498478
}
499479

@@ -508,7 +488,7 @@ fn int_xor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
508488
let v2 = get_value(i2);
509489
Ok(vm.ctx.new_int(v1 ^ v2))
510490
} else {
511-
Err(vm.new_type_error(format!("Cannot xor {} and {}", i.borrow(), i2.borrow())))
491+
Ok(vm.ctx.not_implemented())
512492
}
513493
}
514494

@@ -525,7 +505,7 @@ fn int_rxor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
525505

526506
Ok(vm.ctx.new_int(left_val ^ right_val))
527507
} else {
528-
Err(vm.new_type_error(format!("Cannot rxor {} and {}", i.borrow(), i2.borrow())))
508+
Ok(vm.ctx.not_implemented())
529509
}
530510
}
531511

@@ -540,7 +520,7 @@ fn int_or(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
540520
let v2 = get_value(i2);
541521
Ok(vm.ctx.new_int(v1 | v2))
542522
} else {
543-
Err(vm.new_type_error(format!("Cannot or {} and {}", i.borrow(), i2.borrow())))
523+
Ok(vm.ctx.not_implemented())
544524
}
545525
}
546526

@@ -555,7 +535,7 @@ fn int_and(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
555535
let v2 = get_value(i2);
556536
Ok(vm.ctx.new_int(v1 & v2))
557537
} else {
558-
Err(vm.new_type_error(format!("Cannot and {} and {}", i.borrow(), i2.borrow())))
538+
Ok(vm.ctx.not_implemented())
559539
}
560540
}
561541

vm/src/obj/objlist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ fn list_count(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
228228
let elements = get_elements(zelf);
229229
let mut count: usize = 0;
230230
for element in elements.iter() {
231-
let is_eq = vm._eq(element, value.clone())?;
231+
let is_eq = vm._eq(element.clone(), value.clone())?;
232232
if objbool::boolval(vm, is_eq)? {
233233
count += 1;
234234
}

vm/src/obj/objobject.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use super::super::pyobject::{
33
TypeProtocol,
44
};
55
use super::super::vm::VirtualMachine;
6-
use super::objbool;
76
use super::objstr;
87
use super::objtype;
98
use std::cell::RefCell;
@@ -29,19 +28,19 @@ fn object_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
2928
arg_check!(
3029
vm,
3130
args,
32-
required = [(zelf, Some(vm.ctx.object())), (other, None)]
31+
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
3332
);
34-
Ok(vm.ctx.new_bool(zelf.is(other)))
33+
Ok(vm.ctx.not_implemented())
3534
}
3635

3736
fn object_ne(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
3837
arg_check!(
3938
vm,
4039
args,
41-
required = [(zelf, Some(vm.ctx.object())), (other, None)]
40+
required = [(_zelf, Some(vm.ctx.object())), (_other, None)]
4241
);
43-
let eq = vm.call_method(zelf, "__eq__", vec![other.clone()])?;
44-
objbool::not(vm, &eq)
42+
43+
Ok(vm.ctx.not_implemented())
4544
}
4645

4746
fn object_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/obj/objset.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ pub fn set_contains(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
166166
required = [(set, Some(vm.ctx.set_type())), (needle, None)]
167167
);
168168
for element in get_elements(set).iter() {
169-
match vm.call_method(needle, "__eq__", vec![element.1.clone()]) {
169+
match vm._eq(needle.clone(), element.1.clone()) {
170170
Ok(value) => {
171171
if objbool::get_value(&value) {
172172
return Ok(vm.new_bool(true));

vm/src/obj/objtuple.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ fn tuple_count(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
129129
let elements = get_elements(zelf);
130130
let mut count: usize = 0;
131131
for element in elements.iter() {
132-
let is_eq = vm._eq(element, value.clone())?;
132+
let is_eq = vm._eq(element.clone(), value.clone())?;
133133
if objbool::boolval(vm, is_eq)? {
134134
count += 1;
135135
}

0 commit comments

Comments
 (0)