mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Fix: array with float type should accept integer parameter
This commit is contained in:
1 parent
92d8e2c8da
commit
1150f507e2
2 files changed
+75
-19
No files matched your search
@@ -19,4 +19,16 @@ a = array("b", [0, 1, 2, 3])
|
||||
b = a
|
||||
assert a.__ne__(b) is False
|
||||
b = array("B", [3, 2, 1, 0])
|
||||
assert a.__ne__(b) is True
|
||||
assert a.__ne__(b) is True
|
||||
|
||||
def test_float_with_integer_input():
|
||||
f = array("f", [0, 1, 2.0, 3.0])
|
||||
f.append(4)
|
||||
f.insert(0, -1)
|
||||
assert f.count(4) == 1
|
||||
f.remove(1)
|
||||
assert f.index(0) == 1
|
||||
f[0] = -2
|
||||
assert f == array("f", [-2, 0, 2, 3, 4])
|
||||
|
||||
test_float_with_integer_input()
|
||||
+62
-18
@@ -4,6 +4,7 @@ use crate::common::cell::{
|
||||
};
|
||||
use crate::function::OptionalArg;
|
||||
use crate::obj::objbytes::PyBytesRef;
|
||||
use crate::obj::objfloat::try_float;
|
||||
use crate::obj::objsequence::PySliceableSequence;
|
||||
use crate::obj::objslice::PySliceRef;
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
@@ -11,7 +12,7 @@ use crate::obj::objtype::PyClassRef;
|
||||
use crate::obj::{objbool, objiter};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, IntoPyObject, PyArithmaticValue, PyClassImpl, PyComparisonValue,
|
||||
PyIterable, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
PyIterable, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::VirtualMachine;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -74,7 +75,7 @@ macro_rules! def_array_enum {
|
||||
fn push(&mut self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
match self {
|
||||
$(ArrayContentType::$n(v) => {
|
||||
let val = $t::try_from_object(vm, obj)?;
|
||||
let val = $t::try_into_from_object(vm, obj)?;
|
||||
v.push(val);
|
||||
})*
|
||||
}
|
||||
@@ -92,7 +93,7 @@ macro_rules! def_array_enum {
|
||||
fn insert(&mut self, i: usize, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
match self {
|
||||
$(ArrayContentType::$n(v) => {
|
||||
let val = $t::try_from_object(vm, obj)?;
|
||||
let val = $t::try_into_from_object(vm, obj)?;
|
||||
v.insert(i, val);
|
||||
})*
|
||||
}
|
||||
@@ -102,9 +103,11 @@ macro_rules! def_array_enum {
|
||||
fn count(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
match self {
|
||||
$(ArrayContentType::$n(v) => {
|
||||
Ok(<Option<$t>>::try_from_object(vm, obj)?.map_or(0, |val| {
|
||||
Ok(if let Ok(val) = $t::try_into_from_object(vm, obj) {
|
||||
v.iter().filter(|&&a| a == val).count()
|
||||
}))
|
||||
} else {
|
||||
0
|
||||
})
|
||||
})*
|
||||
}
|
||||
}
|
||||
@@ -112,13 +115,15 @@ macro_rules! def_array_enum {
|
||||
fn remove(&mut self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()>{
|
||||
match self {
|
||||
$(ArrayContentType::$n(v) => {
|
||||
let pos = <Option<$t>>::try_from_object(vm, obj)?.map_or(None, |val| {
|
||||
v.iter().position(|&a| a == val)
|
||||
}).ok_or_else(||vm.new_value_error("array.remove(x): x not in array".to_owned()) )?;
|
||||
v.remove(pos);
|
||||
if let Ok(val) = $t::try_into_from_object(vm, obj) {
|
||||
if let Some(pos) = v.iter().position(|&a| a == val) {
|
||||
v.remove(pos);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Err(vm.new_value_error("array.remove(x): x not in array".to_owned()))
|
||||
})*
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn frombytes(&mut self, b: &[u8]) {
|
||||
@@ -156,12 +161,15 @@ macro_rules! def_array_enum {
|
||||
}
|
||||
}
|
||||
|
||||
fn index(&self, x: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<usize>> {
|
||||
fn index(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
match self {
|
||||
$(ArrayContentType::$n(v) => {
|
||||
Ok(<Option<$t>>::try_from_object(vm, x)?.map_or(None, |val| {
|
||||
v.iter().position(|&a| a == val)
|
||||
}))
|
||||
if let Ok(val) = $t::try_into_from_object(vm, obj) {
|
||||
if let Some(pos) = v.iter().position(|&a| a == val) {
|
||||
return Ok(pos);
|
||||
}
|
||||
}
|
||||
Err(vm.new_value_error("array.index(x): x not in array".to_owned()))
|
||||
})*
|
||||
}
|
||||
}
|
||||
@@ -228,7 +236,7 @@ macro_rules! def_array_enum {
|
||||
Either::A(i) => {
|
||||
let i = self.idx(i, "array assignment", vm)?;
|
||||
match self {
|
||||
$(ArrayContentType::$n(v) => { v[i] = TryFromObject::try_from_object(vm, value)? },)*
|
||||
$(ArrayContentType::$n(v) => { v[i] = $t::try_into_from_object(vm, value)? },)*
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -264,6 +272,44 @@ def_array_enum!(
|
||||
(Double, f64, 'd'),
|
||||
);
|
||||
|
||||
trait TryIntoFromObject: Sized {
|
||||
fn try_into_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self>;
|
||||
}
|
||||
|
||||
macro_rules! adapt_try_into_from_object {
|
||||
($(($t:ty, $f: path),)*) => {$(
|
||||
impl TryIntoFromObject for $t {
|
||||
fn try_into_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
$f(vm, obj)
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
adapt_try_into_from_object!(
|
||||
(i8, i8::try_from_object),
|
||||
(u8, u8::try_from_object),
|
||||
(i16, i16::try_from_object),
|
||||
(u16, u16::try_from_object),
|
||||
(i32, i32::try_from_object),
|
||||
(u32, u32::try_from_object),
|
||||
(i64, i64::try_from_object),
|
||||
(u64, u64::try_from_object),
|
||||
(f32, f32_try_into_from_object),
|
||||
(f64, f64_try_into_from_object),
|
||||
);
|
||||
|
||||
fn f32_try_into_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<f32> {
|
||||
try_float(&obj, vm)?
|
||||
.map(|x| x as f32)
|
||||
.ok_or_else(|| vm.new_type_error(format!("must be real number, not {}", obj.class().name)))
|
||||
}
|
||||
|
||||
fn f64_try_into_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<f64> {
|
||||
try_float(&obj, vm)?
|
||||
.ok_or_else(|| vm.new_type_error(format!("must be real number, not {}", obj.class().name)))
|
||||
}
|
||||
|
||||
#[pyclass(module = "array", name = "array")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyArray {
|
||||
@@ -364,9 +410,7 @@ impl PyArray {
|
||||
|
||||
#[pymethod]
|
||||
fn index(&self, x: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
self.borrow_value()
|
||||
.index(x, vm)?
|
||||
.ok_or_else(|| vm.new_value_error("x not in array".to_owned()))
|
||||
self.borrow_value().index(x, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
|
||||
Reference in new issue
Block a user