Fix sequence protocol concat

This commit is contained in:
Jeong YunWon
2023-03-09 22:43:15 +09:00
parent 788ccffb2b
commit d9fc95c2a1
4 changed files with 14 additions and 5 deletions

View File

@@ -721,7 +721,6 @@ class MmapTests(unittest.TestCase):
self.assertRaises(ValueError, m.write_byte, 42)
self.assertRaises(ValueError, m.write, b'abc')
@unittest.skip('TODO: RUSTPYTHON, Number Protocol is not properly implemented yet')
def test_concat_repeat_exception(self):
m = mmap.mmap(-1, 16)
with self.assertRaises(TypeError):

View File

@@ -232,6 +232,7 @@ impl PyNumberMethods {
}
}
#[derive(Copy, Clone)]
pub enum PyNumberBinaryOpSlot {
Add,
Subtract,

View File

@@ -2,7 +2,7 @@ use crate::{
builtins::{type_::PointerSlot, PyList, PyListRef, PySlice, PyTuple, PyTupleRef},
convert::ToPyObject,
function::PyArithmeticValue,
protocol::PyMapping,
protocol::{PyMapping, PyNumberBinaryOpSlot},
AsObject, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
};
use crossbeam_utils::atomic::AtomicCell;
@@ -118,7 +118,7 @@ impl PySequence<'_> {
// if both arguments apear to be sequences, try fallback to __add__
if self.check() && other.to_sequence(vm).check() {
let ret = vm._add(self.obj, other)?;
let ret = vm.binary_op1(self.obj, other, &PyNumberBinaryOpSlot::Add)?;
if let PyArithmeticValue::Implemented(ret) = PyArithmeticValue::from_object(vm, ret) {
return Ok(ret);
}
@@ -137,7 +137,11 @@ impl PySequence<'_> {
// fallback to __mul__
if self.check() {
let ret = vm._mul(self.obj, &n.to_pyobject(vm))?;
let ret = vm.binary_op1(
self.obj,
&n.to_pyobject(vm),
&PyNumberBinaryOpSlot::Multiply,
)?;
if let PyArithmeticValue::Implemented(ret) = PyArithmeticValue::from_object(vm, ret) {
return Ok(ret);
}

View File

@@ -131,7 +131,12 @@ impl VirtualMachine {
/// b.rop(b,a)[*], a.op(a,b), b.rop(b,a)
///
/// [*] only when Py_TYPE(a) != Py_TYPE(b) && Py_TYPE(b) is a subclass of Py_TYPE(a)
fn binary_op1(&self, a: &PyObject, b: &PyObject, op_slot: &PyNumberBinaryOpSlot) -> PyResult {
pub fn binary_op1(
&self,
a: &PyObject,
b: &PyObject,
op_slot: &PyNumberBinaryOpSlot,
) -> PyResult {
let slot_a = a.class().slots.number.get_left_binary_op(op_slot)?;
let mut slot_b = if b.class().is(a.class()) {
None