mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Make vm.extract_elements generic
This commit is contained in:
@@ -1043,7 +1043,7 @@ impl Frame {
|
||||
|
||||
fn execute_unpack_ex(&self, vm: &VirtualMachine, before: usize, after: usize) -> FrameResult {
|
||||
let value = self.pop_value();
|
||||
let elements = vm.extract_elements(&value)?;
|
||||
let elements = vm.extract_elements::<PyObjectRef>(&value)?;
|
||||
let min_expected = before + after;
|
||||
if elements.len() < min_expected {
|
||||
Err(vm.new_value_error(format!(
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::cell::Cell;
|
||||
use super::objtuple::PyTuple;
|
||||
use super::objtype::{self, PyClassRef};
|
||||
use crate::pyobject::{
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -60,14 +60,10 @@ pub fn get_next_object(
|
||||
}
|
||||
|
||||
/* Retrieve all elements from an iterator */
|
||||
pub fn get_all(vm: &VirtualMachine, iter_obj: &PyObjectRef) -> PyResult<Vec<PyObjectRef>> {
|
||||
pub fn get_all<T: TryFromObject>(vm: &VirtualMachine, iter_obj: &PyObjectRef) -> PyResult<Vec<T>> {
|
||||
let mut elements = vec![];
|
||||
loop {
|
||||
let element = get_next_object(vm, iter_obj)?;
|
||||
match element {
|
||||
Some(v) => elements.push(v),
|
||||
None => break,
|
||||
}
|
||||
while let Some(element) = get_next_object(vm, iter_obj)? {
|
||||
elements.push(T::try_from_object(vm, element)?);
|
||||
}
|
||||
Ok(elements)
|
||||
}
|
||||
|
||||
@@ -941,6 +941,7 @@ where
|
||||
}
|
||||
|
||||
impl TryFromObject for PyObjectRef {
|
||||
#[inline]
|
||||
fn try_from_object(_vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
19
vm/src/vm.rs
19
vm/src/vm.rs
@@ -808,17 +808,22 @@ impl VirtualMachine {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn extract_elements(&self, value: &PyObjectRef) -> PyResult<Vec<PyObjectRef>> {
|
||||
pub fn extract_elements<T: TryFromObject>(&self, value: &PyObjectRef) -> PyResult<Vec<T>> {
|
||||
// Extract elements from item, if possible:
|
||||
let elements = if objtype::isinstance(value, &self.ctx.tuple_type()) {
|
||||
objsequence::get_elements_tuple(value).to_vec()
|
||||
if objtype::isinstance(value, &self.ctx.tuple_type()) {
|
||||
objsequence::get_elements_tuple(value)
|
||||
.iter()
|
||||
.map(|obj| T::try_from_object(self, obj.clone()))
|
||||
.collect()
|
||||
} else if objtype::isinstance(value, &self.ctx.list_type()) {
|
||||
objsequence::get_elements_list(value).to_vec()
|
||||
objsequence::get_elements_list(value)
|
||||
.iter()
|
||||
.map(|obj| T::try_from_object(self, obj.clone()))
|
||||
.collect()
|
||||
} else {
|
||||
let iter = objiter::get_iter(self, value)?;
|
||||
objiter::get_all(self, &iter)?
|
||||
};
|
||||
Ok(elements)
|
||||
objiter::get_all(self, &iter)
|
||||
}
|
||||
}
|
||||
|
||||
// get_attribute should be used for full attribute access (usually from user code).
|
||||
|
||||
Reference in New Issue
Block a user