Skip to content

Commit 471ec26

Browse files
authored
Merge pull request RustPython#4790 from Snowapril/number-protocol-unary-ternary
Modify unary & ternary function fields in number protocol
2 parents 1b66332 + a4a6e8d commit 471ec26

File tree

11 files changed

+285
-136
lines changed

11 files changed

+285
-136
lines changed

Lib/test/test_descr.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4025,8 +4025,6 @@ def __rpow__(self, other):
40254025
a **= b
40264026
self.assertEqual(a, 1)
40274027

4028-
# TODO: RUSTPYTHON
4029-
@unittest.expectedFailure
40304028
def test_ipow_exception_text(self):
40314029
x = None
40324030
with self.assertRaises(TypeError) as cm:

vm/src/builtins/complex.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,13 @@ impl AsNumber for PyComplex {
421421
add: Some(|a, b, vm| PyComplex::number_op(a, b, |a, b, _vm| a + b, vm)),
422422
subtract: Some(|a, b, vm| PyComplex::number_op(a, b, |a, b, _vm| a - b, vm)),
423423
multiply: Some(|a, b, vm| PyComplex::number_op(a, b, |a, b, _vm| a * b, vm)),
424-
power: Some(|a, b, vm| PyComplex::number_op(a, b, inner_pow, vm)),
424+
power: Some(|a, b, c, vm| {
425+
if vm.is_none(c) {
426+
PyComplex::number_op(a, b, inner_pow, vm)
427+
} else {
428+
Err(vm.new_value_error(String::from("complex modulo")))
429+
}
430+
}),
425431
negative: Some(|number, vm| {
426432
let value = PyComplex::number_downcast(number).value;
427433
(-value).to_pyresult(vm)

vm/src/builtins/float.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub struct PyFloat {
3030
}
3131

3232
impl PyFloat {
33-
pub fn to_f64(self) -> f64 {
33+
pub fn to_f64(&self) -> f64 {
3434
self.value
3535
}
3636
}
@@ -549,7 +549,15 @@ impl AsNumber for PyFloat {
549549
multiply: Some(|a, b, vm| PyFloat::number_op(a, b, |a, b, _vm| a * b, vm)),
550550
remainder: Some(|a, b, vm| PyFloat::number_op(a, b, inner_mod, vm)),
551551
divmod: Some(|a, b, vm| PyFloat::number_op(a, b, inner_divmod, vm)),
552-
power: Some(|a, b, vm| PyFloat::number_op(a, b, float_pow, vm)),
552+
power: Some(|a, b, c, vm| {
553+
if vm.is_none(c) {
554+
PyFloat::number_op(a, b, float_pow, vm)
555+
} else {
556+
Err(vm.new_type_error(String::from(
557+
"pow() 3rd argument not allowed unless all arguments are integers",
558+
)))
559+
}
560+
}),
553561
negative: Some(|num, vm| {
554562
let value = PyFloat::number_downcast(num).value;
555563
(-value).to_pyresult(vm)
@@ -562,9 +570,9 @@ impl AsNumber for PyFloat {
562570
boolean: Some(|num, _vm| Ok(PyFloat::number_downcast(num).value.is_zero())),
563571
int: Some(|num, vm| {
564572
let value = PyFloat::number_downcast(num).value;
565-
try_to_bigint(value, vm).map(|x| vm.ctx.new_int(x))
573+
try_to_bigint(value, vm).map(|x| PyInt::from(x).into_pyobject(vm))
566574
}),
567-
float: Some(|num, vm| Ok(PyFloat::number_downcast_exact(num, vm))),
575+
float: Some(|num, vm| Ok(PyFloat::number_downcast_exact(num, vm).into())),
568576
floor_divide: Some(|a, b, vm| PyFloat::number_op(a, b, inner_floordiv, vm)),
569577
true_divide: Some(|a, b, vm| PyFloat::number_op(a, b, inner_div, vm)),
570578
..PyNumberMethods::NOT_IMPLEMENTED

vm/src/builtins/int.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,24 @@ impl PyInt {
745745
multiply: Some(|a, b, vm| PyInt::number_op(a, b, |a, b, _vm| a * b, vm)),
746746
remainder: Some(|a, b, vm| PyInt::number_op(a, b, inner_mod, vm)),
747747
divmod: Some(|a, b, vm| PyInt::number_op(a, b, inner_divmod, vm)),
748-
power: Some(|a, b, vm| PyInt::number_op(a, b, inner_pow, vm)),
748+
power: Some(|a, b, c, vm| {
749+
if let (Some(a), Some(b)) = (
750+
a.payload::<Self>(),
751+
if b.payload_is::<Self>() {
752+
Some(b)
753+
} else {
754+
None
755+
},
756+
) {
757+
if vm.is_none(c) {
758+
a.general_op(b.to_owned(), |a, b| inner_pow(a, b, vm), vm)
759+
} else {
760+
a.modpow(b.to_owned(), c.to_owned(), vm)
761+
}
762+
} else {
763+
Ok(vm.ctx.not_implemented())
764+
}
765+
}),
749766
negative: Some(|num, vm| (&PyInt::number_downcast(num).value).neg().to_pyresult(vm)),
750767
positive: Some(|num, vm| Ok(PyInt::number_downcast_exact(num, vm).into())),
751768
absolute: Some(|num, vm| PyInt::number_downcast(num).value.abs().to_pyresult(vm)),
@@ -756,14 +773,14 @@ impl PyInt {
756773
and: Some(|a, b, vm| PyInt::number_op(a, b, |a, b, _vm| a & b, vm)),
757774
xor: Some(|a, b, vm| PyInt::number_op(a, b, |a, b, _vm| a ^ b, vm)),
758775
or: Some(|a, b, vm| PyInt::number_op(a, b, |a, b, _vm| a | b, vm)),
759-
int: Some(|num, vm| Ok(PyInt::number_downcast_exact(num, vm))),
776+
int: Some(|num, vm| Ok(PyInt::number_downcast_exact(num, vm).into())),
760777
float: Some(|num, vm| {
761778
let zelf = PyInt::number_downcast(num);
762-
try_to_float(&zelf.value, vm).map(|x| vm.ctx.new_float(x))
779+
try_to_float(&zelf.value, vm).map(|x| vm.ctx.new_float(x).into())
763780
}),
764781
floor_divide: Some(|a, b, vm| PyInt::number_op(a, b, inner_floordiv, vm)),
765782
true_divide: Some(|a, b, vm| PyInt::number_op(a, b, inner_truediv, vm)),
766-
index: Some(|num, vm| Ok(PyInt::number_downcast_exact(num, vm))),
783+
index: Some(|num, vm| Ok(PyInt::number_downcast_exact(num, vm).into())),
767784
..PyNumberMethods::NOT_IMPLEMENTED
768785
};
769786

vm/src/frame.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,7 @@ impl ExecutingFrame<'_> {
16541654
bytecode::BinaryOperator::Add => vm._add(a_ref, b_ref),
16551655
bytecode::BinaryOperator::Multiply => vm._mul(a_ref, b_ref),
16561656
bytecode::BinaryOperator::MatrixMultiply => vm._matmul(a_ref, b_ref),
1657-
bytecode::BinaryOperator::Power => vm._pow(a_ref, b_ref),
1657+
bytecode::BinaryOperator::Power => vm._pow(a_ref, b_ref, vm.ctx.none.as_object()),
16581658
bytecode::BinaryOperator::Divide => vm._truediv(a_ref, b_ref),
16591659
bytecode::BinaryOperator::FloorDivide => vm._floordiv(a_ref, b_ref),
16601660
bytecode::BinaryOperator::Modulo => vm._mod(a_ref, b_ref),
@@ -1680,7 +1680,7 @@ impl ExecutingFrame<'_> {
16801680
bytecode::BinaryOperator::Add => vm._iadd(a_ref, b_ref),
16811681
bytecode::BinaryOperator::Multiply => vm._imul(a_ref, b_ref),
16821682
bytecode::BinaryOperator::MatrixMultiply => vm._imatmul(a_ref, b_ref),
1683-
bytecode::BinaryOperator::Power => vm._ipow(a_ref, b_ref),
1683+
bytecode::BinaryOperator::Power => vm._ipow(a_ref, b_ref, vm.ctx.none.as_object()),
16841684
bytecode::BinaryOperator::Divide => vm._itruediv(a_ref, b_ref),
16851685
bytecode::BinaryOperator::FloorDivide => vm._ifloordiv(a_ref, b_ref),
16861686
bytecode::BinaryOperator::Modulo => vm._imod(a_ref, b_ref),

vm/src/protocol/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ pub use iter::{PyIter, PyIterIter, PyIterReturn};
1212
pub use mapping::{PyMapping, PyMappingMethods};
1313
pub use number::{
1414
PyNumber, PyNumberBinaryFunc, PyNumberBinaryOp, PyNumberMethods, PyNumberSlots,
15-
PyNumberUnaryFunc,
15+
PyNumberTernaryOp, PyNumberUnaryFunc,
1616
};
1717
pub use sequence::{PySequence, PySequenceMethods};

0 commit comments

Comments
 (0)