Skip to content

Commit 2ea34c8

Browse files
committed
Make vm.extract_elements generic
1 parent 8542224 commit 2ea34c8

File tree

4 files changed

+18
-16
lines changed

4 files changed

+18
-16
lines changed

vm/src/frame.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ impl Frame {
10431043

10441044
fn execute_unpack_ex(&self, vm: &VirtualMachine, before: usize, after: usize) -> FrameResult {
10451045
let value = self.pop_value();
1046-
let elements = vm.extract_elements(&value)?;
1046+
let elements = vm.extract_elements::<PyObjectRef>(&value)?;
10471047
let min_expected = before + after;
10481048
if elements.len() < min_expected {
10491049
Err(vm.new_value_error(format!(

vm/src/obj/objiter.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::cell::Cell;
77
use super::objtuple::PyTuple;
88
use super::objtype::{self, PyClassRef};
99
use crate::pyobject::{
10-
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
10+
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
1111
};
1212
use crate::vm::VirtualMachine;
1313

@@ -60,14 +60,10 @@ pub fn get_next_object(
6060
}
6161

6262
/* Retrieve all elements from an iterator */
63-
pub fn get_all(vm: &VirtualMachine, iter_obj: &PyObjectRef) -> PyResult<Vec<PyObjectRef>> {
63+
pub fn get_all<T: TryFromObject>(vm: &VirtualMachine, iter_obj: &PyObjectRef) -> PyResult<Vec<T>> {
6464
let mut elements = vec![];
65-
loop {
66-
let element = get_next_object(vm, iter_obj)?;
67-
match element {
68-
Some(v) => elements.push(v),
69-
None => break,
70-
}
65+
while let Some(element) = get_next_object(vm, iter_obj)? {
66+
elements.push(T::try_from_object(vm, element)?);
7167
}
7268
Ok(elements)
7369
}

vm/src/pyobject.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,7 @@ where
941941
}
942942

943943
impl TryFromObject for PyObjectRef {
944+
#[inline]
944945
fn try_from_object(_vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
945946
Ok(obj)
946947
}

vm/src/vm.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -808,17 +808,22 @@ impl VirtualMachine {
808808
Ok(())
809809
}
810810

811-
pub fn extract_elements(&self, value: &PyObjectRef) -> PyResult<Vec<PyObjectRef>> {
811+
pub fn extract_elements<T: TryFromObject>(&self, value: &PyObjectRef) -> PyResult<Vec<T>> {
812812
// Extract elements from item, if possible:
813-
let elements = if objtype::isinstance(value, &self.ctx.tuple_type()) {
814-
objsequence::get_elements_tuple(value).to_vec()
813+
if objtype::isinstance(value, &self.ctx.tuple_type()) {
814+
objsequence::get_elements_tuple(value)
815+
.iter()
816+
.map(|obj| T::try_from_object(self, obj.clone()))
817+
.collect()
815818
} else if objtype::isinstance(value, &self.ctx.list_type()) {
816-
objsequence::get_elements_list(value).to_vec()
819+
objsequence::get_elements_list(value)
820+
.iter()
821+
.map(|obj| T::try_from_object(self, obj.clone()))
822+
.collect()
817823
} else {
818824
let iter = objiter::get_iter(self, value)?;
819-
objiter::get_all(self, &iter)?
820-
};
821-
Ok(elements)
825+
objiter::get_all(self, &iter)
826+
}
822827
}
823828

824829
// get_attribute should be used for full attribute access (usually from user code).

0 commit comments

Comments
 (0)