Skip to content

Commit f486f30

Browse files
committed
Fix int.__divmod__
1 parent dd9a4a1 commit f486f30

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

tests/snippets/builtin_divmod.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
assert divmod(11, 3) == (3, 2)
44
assert divmod(8,11) == (0, 8)
55
assert divmod(0.873, 0.252) == (3.0, 0.11699999999999999)
6+
assert divmod(-86340, 86400) == (-1, 60)
67

78
assert_raises(ZeroDivisionError, lambda: divmod(5, 0), 'divmod by zero')
89
assert_raises(ZeroDivisionError, lambda: divmod(5.0, 0.0), 'divmod by zero')

tests/snippets/ints.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
assert (2).__rmul__(1) == 2
3838
assert (2).__truediv__(1) == 2.0
3939
assert (2).__rtruediv__(1) == 0.5
40+
assert (-2).__divmod__(3) == (-1, 1)
41+
with assertRaises(ZeroDivisionError):
42+
(2).__divmod__(0)
4043
assert (2).__pow__(3) == 8
4144
assert (10).__pow__(-1) == 0.1
4245
assert (2).__rpow__(3) == 9

vm/src/obj/objint.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,17 @@ fn inner_mod(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
146146
}
147147
}
148148

149+
fn inner_divmod(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
150+
if int2.value.is_zero() {
151+
Err(vm.new_zero_division_error("integer division or modulo by zero".to_string()))
152+
} else {
153+
let (div, modulo) = int1.value.div_mod_floor(&int2.value);
154+
Ok(vm
155+
.ctx
156+
.new_tuple(vec![vm.ctx.new_int(div), vm.ctx.new_int(modulo)]))
157+
}
158+
}
159+
149160
#[pyimpl]
150161
impl PyInt {
151162
#[pymethod(name = "__eq__")]
@@ -397,15 +408,8 @@ impl PyInt {
397408
#[pymethod(name = "__divmod__")]
398409
fn divmod(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
399410
if objtype::isinstance(&other, &vm.ctx.int_type()) {
400-
let v2 = get_value(&other);
401-
if *v2 != BigInt::zero() {
402-
let (r1, r2) = self.value.div_rem(v2);
403-
Ok(vm
404-
.ctx
405-
.new_tuple(vec![vm.ctx.new_int(r1), vm.ctx.new_int(r2)]))
406-
} else {
407-
Err(vm.new_zero_division_error("integer divmod by zero".to_string()))
408-
}
411+
let other = other.payload::<PyInt>().unwrap();
412+
inner_divmod(self, &other, vm)
409413
} else {
410414
Ok(vm.ctx.not_implemented())
411415
}

0 commit comments

Comments
 (0)