Skip to content

Commit 40a8890

Browse files
committed
fix vm.to_index now use number protocol
1 parent e519d6f commit 40a8890

File tree

4 files changed

+27
-31
lines changed

4 files changed

+27
-31
lines changed

Lib/test/test_index.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ def __index__(self):
7171
self.assertIs(type(direct_index), int)
7272
#self.assertIs(type(operator_index), int)
7373

74-
# TODO: RUSTPYTHON
75-
@unittest.expectedFailure
7674
def test_index_returns_int_subclass(self):
7775
class BadInt:
7876
def __index__(self):

vm/src/protocol/number.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,11 @@ impl PyNumber<'_> {
129129
format!("__int__ returned non-int (type {})", ret.class()),
130130
1,
131131
vm,
132-
)?
132+
)?;
133+
Ok(vm.ctx.new_int(ret.as_bigint().clone()))
134+
} else {
135+
Ok(ret)
133136
}
134-
Ok(ret)
135137
} else if self.methods(vm).index.is_some() {
136138
self.index(vm)
137139
} else if let Ok(Ok(f)) = vm.get_special_method(self.obj.to_owned(), "__trunc__") {
@@ -165,9 +167,13 @@ impl PyNumber<'_> {
165167
}
166168
}
167169

168-
pub fn index(&self, vm: &VirtualMachine) -> PyResult<PyIntRef> {
170+
pub fn index_opt(&self, vm: &VirtualMachine) -> PyResult<Option<PyIntRef>> {
169171
if self.obj.class().is(PyInt::class(vm)) {
170-
Ok(unsafe { self.obj.to_owned().downcast_unchecked::<PyInt>() })
172+
Ok(Some(unsafe {
173+
self.obj.to_owned().downcast_unchecked::<PyInt>()
174+
}))
175+
} else if let Some(i) = self.obj.downcast_ref::<PyInt>() {
176+
Ok(Some(i.to_owned()))
171177
} else if let Some(f) = self.methods(vm).index {
172178
let ret = f(self, vm)?;
173179
if !ret.class().is(PyInt::class(vm)) {
@@ -176,15 +182,23 @@ impl PyNumber<'_> {
176182
format!("__index__ returned non-int (type {})", ret.class()),
177183
1,
178184
vm,
179-
)?
185+
)?;
186+
Ok(Some(vm.ctx.new_int(ret.as_bigint().clone())))
187+
} else {
188+
Ok(Some(ret))
180189
}
181-
Ok(ret)
182190
} else {
183-
Err(vm.new_type_error(format!(
191+
Ok(None)
192+
}
193+
}
194+
195+
pub fn index(&self, vm: &VirtualMachine) -> PyResult<PyIntRef> {
196+
self.index_opt(vm)?.ok_or_else(|| {
197+
vm.new_type_error(format!(
184198
"'{}' object cannot be interpreted as an integer",
185199
self.obj.class()
186-
)))
187-
}
200+
))
201+
})
188202
}
189203
}
190204

vm/src/types/slot.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::common::{hash::PyHash, lock::PyRwLock};
22
use crate::{
3-
builtins::{PyInt, PyStrRef, PyType, PyTypeRef},
3+
builtins::{PyFloat, PyInt, PyStrRef, PyType, PyTypeRef},
44
bytecode::ComparisonOperator,
55
convert::{ToPyObject, ToPyResult},
66
function::Either,

vm/src/vm/vm_ops.rs

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,18 @@ use crate::{
33
builtins::{PyInt, PyIntRef},
44
function::PyArithmeticValue,
55
object::{AsObject, PyObject, PyObjectRef, PyResult},
6-
protocol::PyIterReturn,
6+
protocol::{PyIterReturn, PyNumber},
77
types::PyComparisonOp,
88
};
99

1010
/// Collection of operators
1111
impl VirtualMachine {
1212
pub fn to_index_opt(&self, obj: PyObjectRef) -> Option<PyResult<PyIntRef>> {
13-
match obj.downcast() {
14-
Ok(val) => Some(Ok(val)),
15-
Err(obj) => self.get_method(obj, "__index__").map(|index| {
16-
// TODO: returning strict subclasses of int in __index__ is deprecated
17-
self.invoke(&index?, ())?.downcast().map_err(|bad| {
18-
self.new_type_error(format!(
19-
"__index__ returned non-int (type {})",
20-
bad.class().name()
21-
))
22-
})
23-
}),
24-
}
13+
PyNumber::from(obj.as_ref()).index_opt(self).transpose()
2514
}
2615

2716
pub fn to_index(&self, obj: &PyObject) -> PyResult<PyIntRef> {
28-
self.to_index_opt(obj.to_owned()).unwrap_or_else(|| {
29-
Err(self.new_type_error(format!(
30-
"'{}' object cannot be interpreted as an integer",
31-
obj.class().name()
32-
)))
33-
})
17+
PyNumber::from(obj).index(self)
3418
}
3519

3620
#[inline]

0 commit comments

Comments
 (0)