Skip to content

Commit 0d7738c

Browse files
committed
PyFuncArgs from rust tuple
1 parent 597b7bd commit 0d7738c

File tree

2 files changed

+54
-16
lines changed

2 files changed

+54
-16
lines changed

vm/src/function.rs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,52 @@
1-
use std::collections::HashMap;
2-
use std::marker::PhantomData;
3-
use std::mem;
4-
use std::ops::RangeInclusive;
5-
6-
use indexmap::IndexMap;
7-
use result_like::impl_option_like;
8-
1+
use self::OptionalArg::*;
92
use crate::exceptions::PyBaseExceptionRef;
103
use crate::obj::objtuple::PyTupleRef;
114
use crate::obj::objtype::{isinstance, PyTypeRef};
125
use crate::pyobject::{
13-
BorrowValue, IntoPyResult, PyObjectRef, PyRef, PyResult, PyThreadingConstraint, PyValue,
14-
TryFromObject, TypeProtocol,
6+
BorrowValue, IntoPyObject, IntoPyResult, PyObjectRef, PyRef, PyResult, PyThreadingConstraint,
7+
PyValue, TryFromObject, TypeProtocol,
158
};
169
use crate::vm::VirtualMachine;
10+
use indexmap::IndexMap;
11+
use result_like::impl_option_like;
12+
use std::collections::HashMap;
13+
use std::marker::PhantomData;
14+
use std::ops::RangeInclusive;
1715

18-
use self::OptionalArg::*;
16+
pub trait IntoFuncArgs {
17+
fn into_args(self, vm: &VirtualMachine) -> PyFuncArgs;
18+
}
19+
20+
impl<T> IntoFuncArgs for T
21+
where
22+
T: Into<PyFuncArgs>,
23+
{
24+
fn into_args(self, _vm: &VirtualMachine) -> PyFuncArgs {
25+
self.into()
26+
}
27+
}
28+
29+
// A tuple of values that each implement `IntoPyObject` represents a sequence of
30+
// arguments that can be bound and passed to a built-in function.
31+
macro_rules! into_func_args_from_tuple {
32+
($(($n:tt, $T:ident)),*) => {
33+
impl<$($T,)*> IntoFuncArgs for ($($T,)*)
34+
where
35+
$($T: IntoPyObject,)*
36+
{
37+
fn into_args(self, vm: &VirtualMachine) -> PyFuncArgs {
38+
let ($($n,)*) = self;
39+
vec![$($n.into_pyobject(vm),)*].into()
40+
}
41+
}
42+
};
43+
}
44+
45+
into_func_args_from_tuple!((v1, T1));
46+
into_func_args_from_tuple!((v1, T1), (v2, T2));
47+
into_func_args_from_tuple!((v1, T1), (v2, T2), (v3, T3));
48+
into_func_args_from_tuple!((v1, T1), (v2, T2), (v3, T3), (v4, T4));
49+
into_func_args_from_tuple!((v1, T1), (v2, T2), (v3, T3), (v4, T4), (v5, T5));
1950

2051
/// The `PyFuncArgs` struct is one of the most used structs then creating
2152
/// a rust function that can be called from python. It holds both positional
@@ -72,7 +103,7 @@ impl From<KwArgs> for PyFuncArgs {
72103

73104
impl FromArgs for PyFuncArgs {
74105
fn from_args(_vm: &VirtualMachine, args: &mut PyFuncArgs) -> Result<Self, ArgumentError> {
75-
Ok(mem::take(args))
106+
Ok(std::mem::take(args))
76107
}
77108
}
78109

@@ -343,12 +374,19 @@ impl<T> Args<T> {
343374
self.0
344375
}
345376
}
377+
346378
impl<T> From<Vec<T>> for Args<T> {
347379
fn from(v: Vec<T>) -> Self {
348380
Args(v)
349381
}
350382
}
351383

384+
impl From<()> for Args<PyObjectRef> {
385+
fn from(_args: ()) -> Self {
386+
Args(Vec::new())
387+
}
388+
}
389+
352390
impl<T> AsRef<[T]> for Args<T> {
353391
fn as_ref(&self) -> &[T] {
354392
&self.0

vm/src/vm.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::common::{hash::HashSecret, lock::PyMutex, rc::PyRc};
1919
use crate::exceptions::{self, PyBaseException, PyBaseExceptionRef};
2020
use crate::frame::{ExecutionResult, Frame, FrameRef};
2121
use crate::frozen;
22-
use crate::function::PyFuncArgs;
22+
use crate::function::{IntoFuncArgs, PyFuncArgs};
2323
use crate::import;
2424
use crate::obj::objbool;
2525
use crate::obj::objcode::{PyCode, PyCodeRef};
@@ -901,7 +901,7 @@ impl VirtualMachine {
901901

902902
pub fn call_method<T>(&self, obj: &PyObjectRef, method_name: &str, args: T) -> PyResult
903903
where
904-
T: Into<PyFuncArgs>,
904+
T: IntoFuncArgs,
905905
{
906906
flame_guard!(format!("call_method({:?})", method_name));
907907

@@ -936,9 +936,9 @@ impl VirtualMachine {
936936
#[inline]
937937
pub fn invoke<T>(&self, func_ref: &PyObjectRef, args: T) -> PyResult
938938
where
939-
T: Into<PyFuncArgs>,
939+
T: IntoFuncArgs,
940940
{
941-
self._invoke(func_ref, args.into())
941+
self._invoke(func_ref, args.into_args(self))
942942
}
943943

944944
/// Call registered trace function.

0 commit comments

Comments
 (0)