fix vm.to_index now use number protocol

This commit is contained in:
Kangzhi Shi authored and Jeong Yunwon committed 2022-05-30 07:36:08 +09:00
1 parent 3e6e348a67
commit 1ed18c012a
3 files changed
+26 -32

No files matched your search

-2
View File
@@ -71,8 +71,6 @@ class BaseTestCase(unittest.TestCase):
self.assertIs(type(direct_index), int)
#self.assertIs(type(operator_index), int)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_index_returns_int_subclass(self):
class BadInt:
def __index__(self):
+23 -9
View File
@@ -134,9 +134,11 @@ impl PyNumber<'_> {
),
1,
vm,
)?
)?;
Ok(vm.ctx.new_int(ret.as_bigint().clone()))
} else {
Ok(ret)
}
Ok(ret)
} else if self.methods(vm).index.is_some() {
self.index(vm)
} else if let Ok(Ok(f)) =
@@ -173,9 +175,13 @@ impl PyNumber<'_> {
}
}
pub fn index(&self, vm: &VirtualMachine) -> PyResult<PyIntRef> {
pub fn index_opt(&self, vm: &VirtualMachine) -> PyResult<Option<PyIntRef>> {
if self.obj.class().is(PyInt::class(vm)) {
Ok(unsafe { self.obj.to_owned().downcast_unchecked::<PyInt>() })
Ok(Some(unsafe {
self.obj.to_owned().downcast_unchecked::<PyInt>()
}))
} else if let Some(i) = self.obj.downcast_ref::<PyInt>() {
Ok(Some(i.to_owned()))
} else if let Some(f) = self.methods(vm).index {
let ret = f(self, vm)?;
if !ret.class().is(PyInt::class(vm)) {
@@ -189,15 +195,23 @@ impl PyNumber<'_> {
),
1,
vm,
)?
)?;
Ok(Some(vm.ctx.new_int(ret.as_bigint().clone())))
} else {
Ok(Some(ret))
}
Ok(ret)
} else {
Err(vm.new_type_error(format!(
Ok(None)
}
}
pub fn index(&self, vm: &VirtualMachine) -> PyResult<PyIntRef> {
self.index_opt(vm)?.ok_or_else(|| {
vm.new_type_error(format!(
"'{}' object cannot be interpreted as an integer",
self.obj.class()
)))
}
))
})
}
pub fn float_opt(&self, vm: &VirtualMachine) -> PyResult<Option<PyRef<PyFloat>>> {
+3 -21
View File
@@ -3,36 +3,18 @@ use crate::{
builtins::{PyInt, PyIntRef, PyStrInterned},
function::PyArithmeticValue,
object::{AsObject, PyObject, PyObjectRef, PyResult},
protocol::PyIterReturn,
protocol::{PyIterReturn, PyNumber},
types::PyComparisonOp,
};
/// Collection of operators
impl VirtualMachine {
pub fn to_index_opt(&self, obj: PyObjectRef) -> Option<PyResult<PyIntRef>> {
match obj.downcast() {
Ok(val) => Some(Ok(val)),
Err(obj) => self
.get_method(obj, identifier!(self, __index__))
.map(|index| {
// TODO: returning strict subclasses of int in __index__ is deprecated
self.invoke(&index?, ())?.downcast().map_err(|bad| {
self.new_type_error(format!(
"__index__ returned non-int (type {})",
bad.class().name()
))
})
}),
}
PyNumber::from(obj.as_ref()).index_opt(self).transpose()
}
pub fn to_index(&self, obj: &PyObject) -> PyResult<PyIntRef> {
self.to_index_opt(obj.to_owned()).unwrap_or_else(|| {
Err(self.new_type_error(format!(
"'{}' object cannot be interpreted as an integer",
obj.class().name()
)))
})
PyNumber::from(obj).index(self)
}
#[inline]