diff --git a/src/shell/helper.rs b/src/shell/helper.rs index 82f71bb9b9..a5afcbe281 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -1,6 +1,6 @@ use rustpython_vm::builtins::{PyDictRef, PyStrRef}; use rustpython_vm::VirtualMachine; -use rustpython_vm::{PyIterable, PyResult, TryFromObject}; +use rustpython_vm::{function::ArgIterable, PyResult, TryFromObject}; pub struct ShellHelper<'vm> { vm: &'vm VirtualMachine, @@ -64,7 +64,7 @@ impl<'vm> ShellHelper<'vm> { let str_iter_method = |obj, name| { let iter = self.vm.call_special_method(obj, name, ())?; - PyIterable::::try_from_object(self.vm, iter)?.iter(self.vm) + ArgIterable::::try_from_object(self.vm, iter)?.iter(self.vm) }; let (word_start, iter1, iter2) = if let Some((last, parents)) = rest.split_last() { diff --git a/vm/src/anystr.rs b/vm/src/anystr.rs index 43e89a6e10..841820b35d 100644 --- a/vm/src/anystr.rs +++ b/vm/src/anystr.rs @@ -1,8 +1,8 @@ use crate::builtins::int::PyIntRef; use crate::cformat::CFormatString; -use crate::function::{single_or_tuple_any, OptionalOption}; +use crate::function::{single_or_tuple_any, OptionalOption, PyIterator}; use crate::vm::VirtualMachine; -use crate::{PyIterator, PyObjectRef, PyResult, TryFromObject, TypeProtocol}; +use crate::{PyObjectRef, PyResult, TryFromObject, TypeProtocol}; use num_traits::{cast::ToPrimitive, sign::Signed}; use std::str::FromStr; diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 4b5887a31b..24c7e2bfb4 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -18,7 +18,7 @@ use crate::common::lock::{ PyMappedRwLockReadGuard, PyMappedRwLockWriteGuard, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard, }; -use crate::function::{FuncArgs, OptionalArg, OptionalOption}; +use crate::function::{ArgIterable, FuncArgs, OptionalArg, OptionalOption}; use crate::sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex}; use crate::slots::{ AsBuffer, Callable, Comparable, Hashable, Iterable, PyComparisonOp, PyIter, Unhashable, @@ -26,8 +26,8 @@ use crate::slots::{ use crate::utils::Either; use crate::vm::VirtualMachine; use crate::{ - IdProtocol, IntoPyObject, PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyIterable, - PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, + IdProtocol, IntoPyObject, PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, + PyRef, PyResult, PyValue, TypeProtocol, }; use bstr::ByteSlice; use crossbeam_utils::atomic::AtomicCell; @@ -413,7 +413,7 @@ impl PyByteArray { } #[pymethod] - fn join(&self, iter: PyIterable, vm: &VirtualMachine) -> PyResult { + fn join(&self, iter: ArgIterable, vm: &VirtualMachine) -> PyResult { Ok(self.inner().join(iter, vm)?.into()) } diff --git a/vm/src/builtins/bytes.rs b/vm/src/builtins/bytes.rs index f41e55053f..61af29c2d1 100644 --- a/vm/src/builtins/bytes.rs +++ b/vm/src/builtins/bytes.rs @@ -11,15 +11,15 @@ use crate::bytesinner::{ }; use crate::byteslike::ArgBytesLike; use crate::common::hash::PyHash; -use crate::function::{OptionalArg, OptionalOption}; +use crate::function::{ArgIterable, OptionalArg, OptionalOption}; use crate::slots::{ AsBuffer, Callable, Comparable, Hashable, Iterable, PyComparisonOp, PyIter, SlotConstructor, }; use crate::utils::Either; use crate::vm::VirtualMachine; use crate::{ - IdProtocol, IntoPyObject, IntoPyResult, PyClassImpl, PyComparisonValue, PyContext, PyIterable, - PyObjectRef, PyRef, PyResult, PyValue, TryFromBorrowedObject, TypeProtocol, + IdProtocol, IntoPyObject, IntoPyResult, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, + PyRef, PyResult, PyValue, TryFromBorrowedObject, TypeProtocol, }; use bstr::ByteSlice; use crossbeam_utils::atomic::AtomicCell; @@ -263,7 +263,7 @@ impl PyBytes { } #[pymethod] - fn join(&self, iter: PyIterable, vm: &VirtualMachine) -> PyResult { + fn join(&self, iter: ArgIterable, vm: &VirtualMachine) -> PyResult { Ok(self.inner.join(iter, vm)?.into()) } diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 535980bd42..d4c422a01d 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -8,13 +8,13 @@ use super::set::PySet; use super::IterStatus; use crate::dictdatatype::{self, DictKey}; use crate::exceptions::PyBaseExceptionRef; -use crate::function::{FuncArgs, KwArgs, OptionalArg}; +use crate::function::{ArgIterable, FuncArgs, KwArgs, OptionalArg}; use crate::iterator; use crate::slots::{Comparable, Hashable, Iterable, PyComparisonOp, PyIter, Unhashable}; use crate::vm::{ReprGuard, VirtualMachine}; use crate::{ IdProtocol, IntoPyObject, ItemProtocol, PyArithmaticValue::*, PyAttributes, PyClassDef, - PyClassImpl, PyComparisonValue, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, + PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, }; @@ -132,7 +132,7 @@ impl PyDict { #[pyclassmethod] fn fromkeys( class: PyTypeRef, - iterable: PyIterable, + iterable: ArgIterable, value: OptionalArg, vm: &VirtualMachine, ) -> PyResult> { diff --git a/vm/src/builtins/iter.rs b/vm/src/builtins/iter.rs index d3264b417a..95f2f53afa 100644 --- a/vm/src/builtins/iter.rs +++ b/vm/src/builtins/iter.rs @@ -9,8 +9,8 @@ use super::{int, PyInt}; use crate::slots::PyIter; use crate::vm::VirtualMachine; use crate::{ - ItemProtocol, PyCallable, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, - TypeProtocol, + function::ArgCallable, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, + PyValue, TypeProtocol, }; /// Marks status of iterator. @@ -112,7 +112,7 @@ impl PyIter for PySequenceIterator { #[pyclass(module = false, name = "callable_iterator")] #[derive(Debug)] pub struct PyCallableIterator { - callable: PyCallable, + callable: ArgCallable, sentinel: PyObjectRef, status: AtomicCell, } @@ -125,7 +125,7 @@ impl PyValue for PyCallableIterator { #[pyimpl(with(PyIter))] impl PyCallableIterator { - pub fn new(callable: PyCallable, sentinel: PyObjectRef) -> Self { + pub fn new(callable: ArgCallable, sentinel: PyObjectRef) -> Self { Self { callable, sentinel, diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index a26693c84e..9e7ae2adb6 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -17,15 +17,15 @@ use super::PyInt; use crate::common::lock::{ PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard, }; -use crate::function::{FuncArgs, OptionalArg}; +use crate::function::{ArgIterable, FuncArgs, OptionalArg}; use crate::sequence::{self, SimpleSeq}; use crate::sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex}; use crate::slots::{Comparable, Hashable, Iterable, PyComparisonOp, PyIter, Unhashable}; use crate::utils::Either; use crate::vm::{ReprGuard, VirtualMachine}; use crate::{ - PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyIterable, PyObjectRef, PyRef, - PyResult, PyValue, TryFromObject, TypeProtocol, + PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, + TryFromObject, TypeProtocol, }; /// Built-in mutable sequence. @@ -196,7 +196,7 @@ impl PyList { match SequenceIndex::try_from_object_for(vm, needle, Self::NAME)? { SequenceIndex::Int(index) => self.setindex(index, value, vm), SequenceIndex::Slice(slice) => { - if let Ok(sec) = PyIterable::try_from_object(vm, value) { + if let Ok(sec) = ArgIterable::try_from_object(vm, value) { return self.setslice(slice, sec, vm); } Err(vm.new_type_error("can only assign an iterable to a slice".to_owned())) @@ -214,7 +214,7 @@ impl PyList { } } - fn setslice(&self, slice: PySliceRef, sec: PyIterable, vm: &VirtualMachine) -> PyResult<()> { + fn setslice(&self, slice: PySliceRef, sec: ArgIterable, vm: &VirtualMachine) -> PyResult<()> { let items: Result, _> = sec.iter(vm)?.collect(); let items = items?; let mut elements = self.borrow_vec_mut(); diff --git a/vm/src/builtins/make_module.rs b/vm/src/builtins/make_module.rs index 128557e12b..4a368a7354 100644 --- a/vm/src/builtins/make_module.rs +++ b/vm/src/builtins/make_module.rs @@ -25,7 +25,9 @@ mod decl { use crate::common::{hash::PyHash, str::to_ascii}; #[cfg(feature = "rustpython-compiler")] use crate::compile; - use crate::function::{Args, FuncArgs, KwArgs, OptionalArg, OptionalOption}; + use crate::function::{ + ArgCallable, ArgIterable, Args, FuncArgs, KwArgs, OptionalArg, OptionalOption, + }; use crate::iterator; use crate::readline::{Readline, ReadlineResult}; use crate::scope::Scope; @@ -34,8 +36,8 @@ mod decl { use crate::vm::VirtualMachine; use crate::{py_io, sysmodule}; use crate::{ - IdProtocol, ItemProtocol, PyArithmaticValue, PyCallable, PyClassImpl, PyIterable, - PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol, + IdProtocol, ItemProtocol, PyArithmaticValue, PyClassImpl, PyObjectRef, PyResult, PyValue, + TryFromObject, TypeProtocol, }; use num_traits::{Signed, Zero}; @@ -45,7 +47,7 @@ mod decl { } #[pyfunction] - fn all(iterable: PyIterable, vm: &VirtualMachine) -> PyResult { + fn all(iterable: ArgIterable, vm: &VirtualMachine) -> PyResult { for item in iterable.iter(vm)? { if !item?.to_bool() { return Ok(false); @@ -55,7 +57,7 @@ mod decl { } #[pyfunction] - fn any(iterable: PyIterable, vm: &VirtualMachine) -> PyResult { + fn any(iterable: ArgIterable, vm: &VirtualMachine) -> PyResult { for item in iterable.iter(vm)? { if item?.to_bool() { return Ok(true); @@ -421,7 +423,7 @@ mod decl { vm: &VirtualMachine, ) -> PyResult { if let OptionalArg::Present(sentinel) = sentinel { - let callable = PyCallable::try_from_object(vm, iter_target)?; + let callable = ArgCallable::try_from_object(vm, iter_target)?; Ok(PyCallableIterator::new(callable, sentinel) .into_ref(vm) .into_object()) @@ -755,7 +757,7 @@ mod decl { #[derive(FromArgs)] pub struct SumArgs { #[pyarg(positional)] - iterable: PyIterable, + iterable: ArgIterable, #[pyarg(any, optional)] start: OptionalArg, } diff --git a/vm/src/builtins/pystr.rs b/vm/src/builtins/pystr.rs index 8f234477d4..4beefd9683 100644 --- a/vm/src/builtins/pystr.rs +++ b/vm/src/builtins/pystr.rs @@ -9,14 +9,14 @@ use super::pytype::PyTypeRef; use crate::anystr::{self, adjust_indices, AnyStr, AnyStrContainer, AnyStrWrapper}; use crate::exceptions::IntoPyException; use crate::format::{FormatSpec, FormatString, FromTemplate}; -use crate::function::{FuncArgs, OptionalArg, OptionalOption}; +use crate::function::{ArgIterable, FuncArgs, OptionalArg, OptionalOption}; use crate::sliceable::PySliceableSequence; use crate::slots::{Comparable, Hashable, Iterable, PyComparisonOp, PyIter, SlotConstructor}; use crate::utils::Either; use crate::VirtualMachine; use crate::{ IdProtocol, IntoPyObject, ItemProtocol, PyClassDef, PyClassImpl, PyComparisonValue, PyContext, - PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryIntoRef, TypeProtocol, + PyObjectRef, PyRef, PyResult, PyValue, TryIntoRef, TypeProtocol, }; use bstr::ByteSlice; use crossbeam_utils::atomic::AtomicCell; @@ -937,7 +937,7 @@ impl PyStr { } #[pymethod] - fn join(&self, iterable: PyIterable, vm: &VirtualMachine) -> PyResult { + fn join(&self, iterable: ArgIterable, vm: &VirtualMachine) -> PyResult { let iter = iterable.iter(vm)?; self.as_str().py_join(iter) } diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index 0483a52f26..96e9d71d56 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -6,14 +6,14 @@ use crate::common::hash::PyHash; use crate::common::rc::PyRc; use crate::dictdatatype; use crate::dictdatatype::DictSize; -use crate::function::{Args, FuncArgs, OptionalArg}; +use crate::function::{ArgIterable, Args, FuncArgs, OptionalArg}; use crate::slots::{ Comparable, Hashable, Iterable, PyComparisonOp, PyIter, SlotConstructor, Unhashable, }; use crate::vm::{ReprGuard, VirtualMachine}; use crate::{ - IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyIterable, PyObjectRef, PyRef, - PyResult, PyValue, TryFromObject, TypeProtocol, + IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, + TryFromObject, TypeProtocol, }; use crossbeam_utils::atomic::AtomicCell; use std::fmt; @@ -73,7 +73,7 @@ struct PySetInner { } impl PySetInner { - fn new(iterable: PyIterable, vm: &VirtualMachine) -> PyResult { + fn new(iterable: ArgIterable, vm: &VirtualMachine) -> PyResult { let set = PySetInner::default(); for item in iterable.iter(vm)? { set.add(item?, vm)?; @@ -124,7 +124,7 @@ impl PySetInner { Ok(true) } - fn union(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn union(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { let set = self.clone(); for item in other.iter(vm)? { set.add(item?, vm)?; @@ -133,7 +133,7 @@ impl PySetInner { Ok(set) } - fn intersection(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn intersection(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { let set = PySetInner::default(); for item in other.iter(vm)? { let obj = item?; @@ -144,7 +144,7 @@ impl PySetInner { Ok(set) } - fn difference(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn difference(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { let set = self.copy(); for item in other.iter(vm)? { set.content.delete_if_exists(vm, &item?)?; @@ -152,7 +152,11 @@ impl PySetInner { Ok(set) } - fn symmetric_difference(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn symmetric_difference( + &self, + other: ArgIterable, + vm: &VirtualMachine, + ) -> PyResult { let new_inner = self.clone(); // We want to remove duplicates in other @@ -165,7 +169,7 @@ impl PySetInner { Ok(new_inner) } - fn issuperset(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn issuperset(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { for item in other.iter(vm)? { if !self.contains(&item?, vm)? { return Ok(false); @@ -174,12 +178,12 @@ impl PySetInner { Ok(true) } - fn issubset(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn issubset(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { let other_set = PySetInner::new(other, vm)?; self.compare(&other_set, PyComparisonOp::Le, vm) } - fn isdisjoint(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn isdisjoint(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { for item in other.iter(vm)? { if self.contains(&item?, vm)? { return Ok(false); @@ -237,7 +241,7 @@ impl PySetInner { } } - fn update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { + fn update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { for iterable in others { for item in iterable.iter(vm)? { self.add(item?, vm)?; @@ -246,7 +250,7 @@ impl PySetInner { Ok(()) } - fn intersection_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { + fn intersection_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { let mut temp_inner = self.copy(); self.clear(); for iterable in others { @@ -261,7 +265,7 @@ impl PySetInner { Ok(()) } - fn difference_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { + fn difference_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { for iterable in others { for item in iterable.iter(vm)? { self.content.delete_if_exists(vm, &item?)?; @@ -272,7 +276,7 @@ impl PySetInner { fn symmetric_difference_update( &self, - others: Args, + others: Args, vm: &VirtualMachine, ) -> PyResult<()> { for iterable in others { @@ -367,7 +371,7 @@ impl PySet { } #[pymethod(magic)] - fn init(&self, iterable: OptionalArg, vm: &VirtualMachine) -> PyResult<()> { + fn init(&self, iterable: OptionalArg, vm: &VirtualMachine) -> PyResult<()> { if self.len() > 0 { self.clear(); } @@ -400,41 +404,41 @@ impl PySet { } #[pymethod] - fn union(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn union(&self, others: Args, vm: &VirtualMachine) -> PyResult { multi_args_set!(vm, others, self, union) } #[pymethod] - fn intersection(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn intersection(&self, others: Args, vm: &VirtualMachine) -> PyResult { multi_args_set!(vm, others, self, intersection) } #[pymethod] - fn difference(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn difference(&self, others: Args, vm: &VirtualMachine) -> PyResult { multi_args_set!(vm, others, self, difference) } #[pymethod] fn symmetric_difference( &self, - others: Args, + others: Args, vm: &VirtualMachine, ) -> PyResult { multi_args_set!(vm, others, self, symmetric_difference) } #[pymethod] - fn issubset(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn issubset(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { self.inner.issubset(other, vm) } #[pymethod] - fn issuperset(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn issuperset(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { self.inner.issuperset(other, vm) } #[pymethod] - fn isdisjoint(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn isdisjoint(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { self.inner.isdisjoint(other, vm) } @@ -512,13 +516,13 @@ impl PySet { } #[pymethod] - fn update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { + fn update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { self.inner.update(others, vm)?; Ok(()) } #[pymethod] - fn intersection_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { + fn intersection_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { self.inner.intersection_update(others, vm)?; Ok(()) } @@ -530,7 +534,7 @@ impl PySet { } #[pymethod] - fn difference_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { + fn difference_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { self.inner.difference_update(others, vm)?; Ok(()) } @@ -544,7 +548,7 @@ impl PySet { #[pymethod] fn symmetric_difference_update( &self, - others: Args, + others: Args, vm: &VirtualMachine, ) -> PyResult<()> { self.inner.symmetric_difference_update(others, vm)?; @@ -667,41 +671,41 @@ impl PyFrozenSet { } #[pymethod] - fn union(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn union(&self, others: Args, vm: &VirtualMachine) -> PyResult { multi_args_frozenset!(vm, others, self, union) } #[pymethod] - fn intersection(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn intersection(&self, others: Args, vm: &VirtualMachine) -> PyResult { multi_args_frozenset!(vm, others, self, intersection) } #[pymethod] - fn difference(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn difference(&self, others: Args, vm: &VirtualMachine) -> PyResult { multi_args_frozenset!(vm, others, self, difference) } #[pymethod] fn symmetric_difference( &self, - others: Args, + others: Args, vm: &VirtualMachine, ) -> PyResult { multi_args_frozenset!(vm, others, self, symmetric_difference) } #[pymethod] - fn issubset(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn issubset(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { self.inner.issubset(other, vm) } #[pymethod] - fn issuperset(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn issuperset(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { self.inner.issuperset(other, vm) } #[pymethod] - fn isdisjoint(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult { + fn isdisjoint(&self, other: ArgIterable, vm: &VirtualMachine) -> PyResult { self.inner.isdisjoint(other, vm) } @@ -781,7 +785,7 @@ impl Iterable for PyFrozenSet { } struct SetIterable { - iterable: Args, + iterable: Args, } impl TryFromObject for SetIterable { @@ -793,7 +797,7 @@ impl TryFromObject for SetIterable { // the class lease needs to be drop to be able to return the object drop(class); Ok(SetIterable { - iterable: Args::new(vec![PyIterable::try_from_object(vm, obj)?]), + iterable: Args::new(vec![ArgIterable::try_from_object(vm, obj)?]), }) } else { Err(vm.new_type_error(format!("{} is not a subtype of set or frozenset", class))) diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index a88215b29a..fb0fbdc441 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -11,7 +11,7 @@ use crate::slots::PyComparisonOp; use crate::utils::Either; use crate::vm::VirtualMachine; use crate::{ - IdProtocol, PyComparisonValue, PyIterable, PyObjectRef, PyResult, PyValue, + function::ArgIterable, IdProtocol, PyComparisonValue, PyObjectRef, PyResult, PyValue, TryFromBorrowedObject, }; use bstr::ByteSlice; @@ -556,7 +556,7 @@ impl PyBytesInner { pub fn join( &self, - iterable: PyIterable, + iterable: ArgIterable, vm: &VirtualMachine, ) -> PyResult> { let iter = iterable.iter(vm)?; diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index c598bc9e90..2971c6f292 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -4,15 +4,13 @@ use crate::builtins::singletons::{PyNone, PyNoneRef}; use crate::builtins::traceback::PyTracebackRef; use crate::builtins::tuple::{PyTuple, PyTupleRef}; use crate::common::lock::PyRwLock; -use crate::function::FuncArgs; +use crate::function::{ArgIterable, FuncArgs}; use crate::py_io::{self, Write}; use crate::sysmodule; use crate::types::create_type_with_slots; -use crate::StaticType; -use crate::VirtualMachine; use crate::{ - IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, - PyValue, TryFromObject, TypeProtocol, + IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, + StaticType, TryFromObject, TypeProtocol, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; @@ -83,7 +81,7 @@ impl PyBaseException { } #[pyproperty(setter)] - fn set_args(&self, args: PyIterable, vm: &VirtualMachine) -> PyResult<()> { + fn set_args(&self, args: ArgIterable, vm: &VirtualMachine) -> PyResult<()> { let args = args.iter(vm)?.collect::>>()?; *self.args.write() = PyTupleRef::with_elements(args, &vm.ctx); Ok(()) diff --git a/vm/src/function.rs b/vm/src/function.rs index 8ef464be1e..c9fefc835d 100644 --- a/vm/src/function.rs +++ b/vm/src/function.rs @@ -1,3 +1,5 @@ +mod argument; + use self::OptionalArg::*; use crate::builtins::pytype::PyTypeRef; use crate::builtins::tuple::PyTupleRef; @@ -13,6 +15,8 @@ use result_like::impl_option_like; use std::marker::PhantomData; use std::ops::RangeInclusive; +pub use argument::{ArgCallable, ArgIterable, PyIterator}; + pub trait IntoFuncArgs: Sized { fn into_args(self, vm: &VirtualMachine) -> FuncArgs; fn into_method_args(self, obj: PyObjectRef, vm: &VirtualMachine) -> FuncArgs { diff --git a/vm/src/function/argument.rs b/vm/src/function/argument.rs new file mode 100644 index 0000000000..8b7a1d1adc --- /dev/null +++ b/vm/src/function/argument.rs @@ -0,0 +1,113 @@ +use super::IntoFuncArgs; +use crate::builtins::iter::PySequenceIterator; +use crate::{ + iterator, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine, +}; +use std::marker::PhantomData; + +#[derive(Clone, Debug)] +pub struct ArgCallable { + obj: PyObjectRef, +} + +impl ArgCallable { + #[inline] + pub fn invoke(&self, args: impl IntoFuncArgs, vm: &VirtualMachine) -> PyResult { + vm.invoke(&self.obj, args) + } + + #[inline] + pub fn into_object(self) -> PyObjectRef { + self.obj + } +} + +impl TryFromObject for ArgCallable { + fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { + if vm.is_callable(&obj) { + Ok(ArgCallable { obj }) + } else { + Err(vm.new_type_error(format!("'{}' object is not callable", obj.class().name()))) + } + } +} + +/// An iterable Python object. +/// +/// `ArgIterable` implements `FromArgs` so that a built-in function can accept +/// an object that is required to conform to the Python iterator protocol. +/// +/// ArgIterable can optionally perform type checking and conversions on iterated +/// objects using a generic type parameter that implements `TryFromObject`. +pub struct ArgIterable { + iterable: PyObjectRef, + iterfn: Option, + _item: PhantomData, +} + +impl ArgIterable { + /// Returns an iterator over this sequence of objects. + /// + /// This operation may fail if an exception is raised while invoking the + /// `__iter__` method of the iterable object. + pub fn iter<'a>(&self, vm: &'a VirtualMachine) -> PyResult> { + let iter_obj = match self.iterfn { + Some(f) => f(self.iterable.clone(), vm)?, + None => PySequenceIterator::new(self.iterable.clone()).into_object(vm), + }; + + let length_hint = iterator::length_hint(vm, iter_obj.clone())?; + + Ok(PyIterator { + vm, + obj: iter_obj, + length_hint, + _item: PhantomData, + }) + } +} + +impl TryFromObject for ArgIterable +where + T: TryFromObject, +{ + fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { + let iterfn; + { + let cls = obj.class(); + iterfn = cls.mro_find_map(|x| x.slots.iter.load()); + if iterfn.is_none() && !cls.has_attr("__getitem__") { + return Err(vm.new_type_error(format!("'{}' object is not iterable", cls.name()))); + } + } + Ok(ArgIterable { + iterable: obj, + iterfn, + _item: PhantomData, + }) + } +} + +pub struct PyIterator<'a, T> { + vm: &'a VirtualMachine, + obj: PyObjectRef, + length_hint: Option, + _item: PhantomData, +} + +impl<'a, T> Iterator for PyIterator<'a, T> +where + T: TryFromObject, +{ + type Item = PyResult; + + fn next(&mut self) -> Option { + iterator::get_next_object(self.vm, &self.obj) + .transpose() + .map(|x| x.and_then(|obj| T::try_from_object(self.vm, obj))) + } + + fn size_hint(&self) -> (usize, Option) { + (self.length_hint.unwrap_or(0), self.length_hint) + } +} diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 15c92bb162..3b8612c1f7 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -4,7 +4,6 @@ use num_traits::ToPrimitive; use std::any::Any; use std::collections::HashMap; use std::fmt; -use std::marker::PhantomData; use std::ops::Deref; use crate::builtins::builtinfunc::PyNativeFuncDef; @@ -18,7 +17,6 @@ use crate::builtins::float::PyFloat; use crate::builtins::function::PyBoundMethod; use crate::builtins::getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet}; use crate::builtins::int::{PyInt, PyIntRef}; -use crate::builtins::iter::PySequenceIterator; use crate::builtins::list::PyList; use crate::builtins::namespace::PyNamespace; use crate::builtins::object; @@ -35,7 +33,6 @@ use crate::common::static_cell; use crate::dictdatatype::Dict; use crate::exceptions::{self, PyBaseExceptionRef}; use crate::function::{IntoFuncArgs, IntoPyNativeFunc}; -use crate::iterator; pub use crate::pyobjectrc::{PyObject, PyObjectRef, PyObjectWeak, PyRef, PyWeakRef}; use crate::slots::{PyTpFlags, PyTypeSlots}; use crate::types::{create_type_with_slots, TypeZoo}; @@ -533,33 +530,6 @@ impl TryIntoRef for PyRefExact { } } -#[derive(Clone, Debug)] -pub struct PyCallable { - obj: PyObjectRef, -} - -impl PyCallable { - #[inline] - pub fn invoke(&self, args: impl IntoFuncArgs, vm: &VirtualMachine) -> PyResult { - vm.invoke(&self.obj, args) - } - - #[inline] - pub fn into_object(self) -> PyObjectRef { - self.obj - } -} - -impl TryFromObject for PyCallable { - fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { - if vm.is_callable(&obj) { - Ok(PyCallable { obj }) - } else { - Err(vm.new_type_error(format!("'{}' object is not callable", obj.class().name()))) - } - } -} - pub trait IdProtocol { fn get_id(&self) -> usize; fn is(&self, other: &T) -> bool @@ -725,86 +695,6 @@ where } } -/// An iterable Python object. -/// -/// `PyIterable` implements `FromArgs` so that a built-in function can accept -/// an object that is required to conform to the Python iterator protocol. -/// -/// PyIterable can optionally perform type checking and conversions on iterated -/// objects using a generic type parameter that implements `TryFromObject`. -pub struct PyIterable { - iterable: PyObjectRef, - iterfn: Option, - _item: PhantomData, -} - -impl PyIterable { - /// Returns an iterator over this sequence of objects. - /// - /// This operation may fail if an exception is raised while invoking the - /// `__iter__` method of the iterable object. - pub fn iter<'a>(&self, vm: &'a VirtualMachine) -> PyResult> { - let iter_obj = match self.iterfn { - Some(f) => f(self.iterable.clone(), vm)?, - None => PySequenceIterator::new(self.iterable.clone()).into_object(vm), - }; - - let length_hint = iterator::length_hint(vm, iter_obj.clone())?; - - Ok(PyIterator { - vm, - obj: iter_obj, - length_hint, - _item: PhantomData, - }) - } -} - -impl TryFromObject for PyIterable -where - T: TryFromObject, -{ - fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { - let iterfn; - { - let cls = obj.class(); - iterfn = cls.mro_find_map(|x| x.slots.iter.load()); - if iterfn.is_none() && !cls.has_attr("__getitem__") { - return Err(vm.new_type_error(format!("'{}' object is not iterable", cls.name()))); - } - } - Ok(PyIterable { - iterable: obj, - iterfn, - _item: PhantomData, - }) - } -} - -pub struct PyIterator<'a, T> { - vm: &'a VirtualMachine, - obj: PyObjectRef, - length_hint: Option, - _item: PhantomData, -} - -impl<'a, T> Iterator for PyIterator<'a, T> -where - T: TryFromObject, -{ - type Item = PyResult; - - fn next(&mut self) -> Option { - iterator::get_next_object(self.vm, &self.obj) - .transpose() - .map(|x| x.and_then(|obj| T::try_from_object(self.vm, obj))) - } - - fn size_hint(&self) -> (usize, Option) { - (self.length_hint.unwrap_or(0), self.length_hint) - } -} - impl TryFromObject for PyObjectRef { #[inline] fn try_from_object(_vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { @@ -919,13 +809,6 @@ impl IntoPyObject for PyRef { } } -impl IntoPyObject for PyCallable { - #[inline] - fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { - self.into_object() - } -} - impl IntoPyObject for PyObjectRef { #[inline] fn into_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { diff --git a/vm/src/stdlib/array.rs b/vm/src/stdlib/array.rs index 0a04f60643..6baa015a7b 100644 --- a/vm/src/stdlib/array.rs +++ b/vm/src/stdlib/array.rs @@ -17,11 +17,11 @@ mod array { PyStr, PyStrRef, PyTypeRef, }, byteslike::ArgBytesLike, - function::OptionalArg, + function::{ArgIterable, OptionalArg}, sliceable::{saturate_index, PySliceableSequence, PySliceableSequenceMut, SequenceIndex}, slots::{AsBuffer, Comparable, Iterable, PyComparisonOp, PyIter, SlotConstructor}, - IdProtocol, IntoPyObject, IntoPyResult, PyComparisonValue, PyIterable, PyObjectRef, PyRef, - PyResult, PyValue, StaticType, TryFromObject, TypeProtocol, VirtualMachine, + IdProtocol, IntoPyObject, IntoPyResult, PyComparisonValue, PyObjectRef, PyRef, PyResult, + PyValue, StaticType, TryFromObject, TypeProtocol, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; use itertools::Itertools; @@ -648,7 +648,7 @@ mod array { } } else if init.payload_is::() || init.payload_is::() { init.try_bytes_like(vm, |x| array.frombytes(x))?; - } else if let Ok(iter) = PyIterable::try_from_object(vm, init.clone()) { + } else if let Ok(iter) = ArgIterable::try_from_object(vm, init.clone()) { for obj in iter.iter(vm)? { array.push(obj?, vm)?; } @@ -712,7 +712,7 @@ mod array { } else if let Some(array) = obj.payload::() { w.iadd(&*array.read(), vm) } else { - let iter = PyIterable::try_from_object(vm, obj)?; + let iter = ArgIterable::try_from_object(vm, obj)?; // zelf.extend_from_iterable(iter, vm) for obj in iter.iter(vm)? { w.push(obj?, vm)?; diff --git a/vm/src/stdlib/csv.rs b/vm/src/stdlib/csv.rs index 49803ef60f..85a08c64e3 100644 --- a/vm/src/stdlib/csv.rs +++ b/vm/src/stdlib/csv.rs @@ -1,12 +1,12 @@ use crate::common::lock::PyMutex; use crate::{ builtins::{PyStr, PyStrRef, PyTypeRef}, - function::{ArgumentError, FromArgs, FuncArgs}, + function::{ArgIterable, ArgumentError, FromArgs, FuncArgs}, iterator, slots::PyIter, types::create_simple_type, - PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, StaticType, TryFromObject, - TypeProtocol, VirtualMachine, + PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, StaticType, TryFromObject, TypeProtocol, + VirtualMachine, }; use itertools::{self, Itertools}; use std::fmt; @@ -217,7 +217,7 @@ impl Writer { }}; } - let row = PyIterable::try_from_object(vm, row)?; + let row = ArgIterable::try_from_object(vm, row)?; for field in row.iter(vm)? { let field: PyObjectRef = field?; let stringified; @@ -255,7 +255,7 @@ impl Writer { } #[pymethod] - fn writerows(&self, rows: PyIterable, vm: &VirtualMachine) -> PyResult<()> { + fn writerows(&self, rows: ArgIterable, vm: &VirtualMachine) -> PyResult<()> { for row in rows.iter(vm)? { self.writerow(row?, vm)?; } diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index ba5b318a95..cbf9e26889 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -90,13 +90,13 @@ mod _io { }; use crate::common::rc::PyRc; use crate::exceptions::{self, IntoPyException, PyBaseExceptionRef}; - use crate::function::{FuncArgs, OptionalArg, OptionalOption}; + use crate::function::{ArgIterable, FuncArgs, OptionalArg, OptionalOption}; use crate::slots::SlotConstructor; use crate::utils::Either; use crate::vm::{ReprGuard, VirtualMachine}; use crate::{ - IdProtocol, IntoPyObject, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, - StaticType, TryFromObject, TypeProtocol, + IdProtocol, IntoPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, StaticType, + TryFromObject, TypeProtocol, }; #[allow(clippy::let_and_return)] @@ -463,7 +463,7 @@ mod _io { } let hint = hint as usize; let mut ret = Vec::new(); - let it = PyIterable::try_from_object(vm, instance)?; + let it = ArgIterable::try_from_object(vm, instance)?; let mut full_len = 0; for line in it.iter(vm)? { let line = line?; @@ -480,7 +480,7 @@ mod _io { #[pymethod] fn writelines( instance: PyObjectRef, - lines: PyIterable, + lines: ArgIterable, vm: &VirtualMachine, ) -> PyResult<()> { check_closed(&instance, vm)?; diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index 2b17ff9cf0..95cd5433d0 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -8,11 +8,11 @@ mod decl { }; use crate::{ builtins::{int, PyInt, PyIntRef, PyTupleRef, PyTypeRef}, - function::{Args, FuncArgs, OptionalArg, OptionalOption}, + function::{ArgCallable, Args, FuncArgs, OptionalArg, OptionalOption}, iterator::{call_next, get_iter, get_next_object}, slots::{PyIter, SlotConstructor}, - IdProtocol, IntoPyObject, PyCallable, PyObjectRef, PyRef, PyResult, PyValue, PyWeakRef, - StaticType, TypeProtocol, VirtualMachine, + IdProtocol, IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue, PyWeakRef, StaticType, + TypeProtocol, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; use num_bigint::BigInt; @@ -443,7 +443,7 @@ mod decl { #[pyclass(name = "dropwhile")] #[derive(Debug, PyValue)] struct PyItertoolsDropwhile { - predicate: PyCallable, + predicate: ArgCallable, iterable: PyObjectRef, start_flag: AtomicCell, } @@ -451,7 +451,7 @@ mod decl { #[derive(FromArgs)] struct DropwhileNewArgs { #[pyarg(positional)] - predicate: PyCallable, + predicate: ArgCallable, #[pyarg(positional)] iterable: PyObjectRef, } diff --git a/vm/src/stdlib/math.rs b/vm/src/stdlib/math.rs index 9f1ff57a09..6da60ff8e8 100644 --- a/vm/src/stdlib/math.rs +++ b/vm/src/stdlib/math.rs @@ -5,9 +5,9 @@ use crate::{ builtins::{try_bigint_to_f64, try_f64_to_bigint, IntoPyFloat, PyFloatRef, PyInt, PyIntRef}, - function::{Args, OptionalArg}, + function::{ArgIterable, Args, OptionalArg}, utils::Either, - PyIterable, PyObjectRef, PyResult, PySequence, TypeProtocol, VirtualMachine, + PyObjectRef, PyResult, PySequence, TypeProtocol, VirtualMachine, }; use num_bigint::BigInt; use num_traits::{One, Signed, Zero}; @@ -440,7 +440,7 @@ fn math_lcm(args: Args) -> BigInt { math_perf_arb_len_int_op(args, |x, y| x.lcm(y.as_bigint()), BigInt::one()) } -fn math_fsum(iter: PyIterable, vm: &VirtualMachine) -> PyResult { +fn math_fsum(iter: ArgIterable, vm: &VirtualMachine) -> PyResult { let mut partials = vec![]; let mut special_sum = 0.0; let mut inf_sum = 0.0; @@ -704,7 +704,7 @@ fn math_remainder(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResu #[derive(FromArgs)] struct ProdArgs { #[pyarg(positional)] - iterable: PyIterable, + iterable: ArgIterable, #[pyarg(named, optional)] start: OptionalArg, } diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 0e15a6afd8..eaf702e719 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -2931,7 +2931,10 @@ mod posix { // cfg from nix #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] #[pyfunction] - fn setgroups(group_ids: crate::PyIterable, vm: &VirtualMachine) -> PyResult<()> { + fn setgroups( + group_ids: crate::function::ArgIterable, + vm: &VirtualMachine, + ) -> PyResult<()> { let gids = group_ids .iter(vm)? .map(|entry| match entry { @@ -2978,13 +2981,13 @@ mod posix { #[pyarg(positional)] path: PyPathLike, #[pyarg(positional)] - args: crate::PyIterable, + args: crate::function::ArgIterable, #[pyarg(positional)] env: crate::builtins::dict::PyMapping, #[pyarg(named, default)] - file_actions: Option>, + file_actions: Option>, #[pyarg(named, default)] - setsigdef: Option>, + setsigdef: Option>, } #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))] diff --git a/vm/src/stdlib/sre.rs b/vm/src/stdlib/sre.rs index 72622db255..8c28a43f41 100644 --- a/vm/src/stdlib/sre.rs +++ b/vm/src/stdlib/sre.rs @@ -9,10 +9,10 @@ mod _sre { PyTypeRef, }, common::hash::PyHash, - function::{Args, OptionalArg}, + function::{ArgCallable, Args, OptionalArg}, slots::{Comparable, Hashable}, - IntoPyObject, ItemProtocol, PyCallable, PyComparisonValue, PyObjectRef, PyRef, PyResult, - PyValue, StaticType, TryFromBorrowedObject, TryFromObject, VirtualMachine, + IntoPyObject, ItemProtocol, PyComparisonValue, PyObjectRef, PyRef, PyResult, PyValue, + StaticType, TryFromBorrowedObject, TryFromObject, VirtualMachine, }; use core::str; use crossbeam_utils::atomic::AtomicCell; @@ -104,7 +104,7 @@ mod _sre { #[derive(FromArgs)] struct SubArgs { #[pyarg(any)] - // repl: Either, + // repl: Either, repl: PyObjectRef, #[pyarg(any)] string: PyObjectRef, @@ -298,7 +298,7 @@ mod _sre { } .into_ref(vm); let search = vm.get_method(scanner.into_object(), "search").unwrap()?; - let search = PyCallable::try_from_object(vm, search)?; + let search = ArgCallable::try_from_object(vm, search)?; let iterator = PyCallableIterator::new(search, vm.ctx.none()); Ok(iterator) } diff --git a/vm/src/stdlib/ssl.rs b/vm/src/stdlib/ssl.rs index 5c2fb46d4a..9595dcba7e 100644 --- a/vm/src/stdlib/ssl.rs +++ b/vm/src/stdlib/ssl.rs @@ -4,12 +4,12 @@ use crate::{ builtins::{pytype, weakref::PyWeak, PyStrRef, PyTypeRef}, byteslike::{ArgBytesLike, ArgMemoryBuffer, ArgStrOrBytesLike}, exceptions::{create_exception_type, IntoPyException, PyBaseExceptionRef}, - function::OptionalArg, + function::{ArgCallable, OptionalArg}, slots::SlotConstructor, stdlib::os::PyPathLike, utils::{Either, ToCString}, - IntoPyObject, ItemProtocol, PyCallable, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, - StaticType, VirtualMachine, + IntoPyObject, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, StaticType, + VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; use foreign_types_shared::{ForeignType, ForeignTypeRef}; @@ -636,7 +636,7 @@ struct LoadCertChainArgs { #[pyarg(any, optional)] keyfile: Option, #[pyarg(any, optional)] - password: Option>, + password: Option>, } struct SocketTimeout { diff --git a/vm/src/stdlib/thread.rs b/vm/src/stdlib/thread.rs index 99f787a076..1cfa3e8a50 100644 --- a/vm/src/stdlib/thread.rs +++ b/vm/src/stdlib/thread.rs @@ -3,12 +3,12 @@ use crate::{ builtins::{PyDictRef, PyStrRef, PyTupleRef, PyTypeRef}, exceptions::{self, IntoPyException}, - function::{FuncArgs, KwArgs, OptionalArg}, + function::{ArgCallable, FuncArgs, KwArgs, OptionalArg}, py_io, slots::{SlotGetattro, SlotSetattro}, utils::Either, - IdProtocol, ItemProtocol, PyCallable, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, - StaticType, TypeProtocol, VirtualMachine, + IdProtocol, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, StaticType, + TypeProtocol, VirtualMachine, }; use parking_lot::{ lock_api::{RawMutex as RawMutexT, RawMutexTimed, RawReentrantMutex}, @@ -209,7 +209,7 @@ fn _thread_allocate_lock() -> PyLock { } fn _thread_start_new_thread( - func: PyCallable, + func: ArgCallable, args: PyTupleRef, kwargs: OptionalArg, vm: &VirtualMachine, @@ -238,7 +238,7 @@ fn _thread_start_new_thread( .map_err(|err| err.into_pyexception(vm)) } -fn run_thread(func: PyCallable, args: FuncArgs, vm: &VirtualMachine) { +fn run_thread(func: ArgCallable, args: FuncArgs, vm: &VirtualMachine) { match func.invoke(args, vm) { Ok(_obj) => {} Err(e) if e.isinstance(&vm.ctx.exceptions.system_exit) => {} diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index 47ff845376..04d2a6e2f9 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -4,11 +4,10 @@ use wasm_bindgen::JsCast; use wasm_bindgen_futures::JsFuture; use rustpython_vm::builtins::{PyDictRef, PyStrRef, PyTypeRef}; -use rustpython_vm::function::OptionalArg; +use rustpython_vm::function::{ArgCallable, OptionalArg}; use rustpython_vm::import::import_file; -use rustpython_vm::VirtualMachine; use rustpython_vm::{ - IntoPyObject, PyCallable, PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue, StaticType, + IntoPyObject, PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue, StaticType, VirtualMachine, }; use crate::{convert, js_module::PyPromise, vm_class::weak_vm, wasm_builtins::window}; @@ -110,7 +109,7 @@ fn browser_fetch(url: PyStrRef, args: FetchArgs, vm: &VirtualMachine) -> PyResul Ok(PyPromise::from_future(future).into_object(vm)) } -fn browser_request_animation_frame(func: PyCallable, vm: &VirtualMachine) -> PyResult { +fn browser_request_animation_frame(func: ArgCallable, vm: &VirtualMachine) -> PyResult { use std::{cell::RefCell, rc::Rc}; // this basic setup for request_animation_frame taken from: diff --git a/wasm/lib/src/js_module.rs b/wasm/lib/src/js_module.rs index 55f9b99ba5..b63fd87d8d 100644 --- a/wasm/lib/src/js_module.rs +++ b/wasm/lib/src/js_module.rs @@ -13,8 +13,8 @@ use rustpython_vm::slots::PyIter; use rustpython_vm::types::create_simple_type; use rustpython_vm::VirtualMachine; use rustpython_vm::{ - IntoPyObject, PyCallable, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, StaticType, - TryFromObject, + function::ArgCallable, IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, + StaticType, TryFromObject, }; #[wasm_bindgen(inline_js = " @@ -459,8 +459,8 @@ impl PyPromise { #[pymethod] fn then( &self, - on_fulfill: OptionalOption, - on_reject: OptionalOption, + on_fulfill: OptionalOption, + on_reject: OptionalOption, vm: &VirtualMachine, ) -> PyResult { let (on_fulfill, on_reject) = (on_fulfill.flatten(), on_reject.flatten()); @@ -499,9 +499,16 @@ impl PyPromise { Ok(PyPromise::from_future(ret_future)) } - PromiseKind::PyProm { then } => { - Self::cast_result(vm.invoke(then, (on_fulfill, on_reject)), vm) - } + PromiseKind::PyProm { then } => Self::cast_result( + vm.invoke( + then, + ( + on_fulfill.map(|c| c.into_object()), + on_reject.map(|c| c.into_object()), + ), + ), + vm, + ), PromiseKind::PyResolved(res) => match on_fulfill { Some(resolve) => Self::cast_result(resolve.invoke((res.clone(),), vm), vm), None => Ok(self.clone()), @@ -516,7 +523,7 @@ impl PyPromise { #[pymethod] fn catch( &self, - on_reject: OptionalOption, + on_reject: OptionalOption, vm: &VirtualMachine, ) -> PyResult { self.then(OptionalArg::Present(None), on_reject, vm)