Skip to content

Commit 1fda3ba

Browse files
committed
impl PyNativeFuncInternal for &Py<Self> form
1 parent f314328 commit 1fda3ba

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

vm/src/function/builtin.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{FromArgs, FuncArgs};
22
use crate::{
3-
convert::ToPyResult, object::PyThreadingConstraint, PyPayload, PyRef, PyResult, VirtualMachine,
3+
convert::ToPyResult, object::PyThreadingConstraint, Py, PyPayload, PyRef, PyResult,
4+
VirtualMachine,
45
};
56
use std::marker::PhantomData;
67

@@ -59,6 +60,8 @@ use sealed::PyNativeFuncInternal;
5960
#[doc(hidden)]
6061
pub struct OwnedParam<T>(PhantomData<T>);
6162
#[doc(hidden)]
63+
pub struct BorrowedParam<T>(PhantomData<T>);
64+
#[doc(hidden)]
6265
pub struct RefParam<T>(PhantomData<T>);
6366

6467
// This is the "magic" that allows rust functions of varying signatures to
@@ -80,6 +83,20 @@ macro_rules! into_py_native_func_tuple {
8083
}
8184
}
8285

86+
impl<F, S, $($T,)* R> PyNativeFuncInternal<(BorrowedParam<S>, $(OwnedParam<$T>,)*), R, VirtualMachine> for F
87+
where
88+
F: Fn(&Py<S>, $($T,)* &VirtualMachine) -> R + PyThreadingConstraint + 'static,
89+
S: PyPayload,
90+
$($T: FromArgs,)*
91+
R: ToPyResult,
92+
{
93+
fn call_(&self, vm: &VirtualMachine, args: FuncArgs) -> PyResult {
94+
let (zelf, $($n,)*) = args.bind::<(PyRef<S>, $($T,)*)>(vm)?;
95+
96+
(self)(&zelf, $($n,)* vm).to_pyresult(vm)
97+
}
98+
}
99+
83100
impl<F, S, $($T,)* R> PyNativeFuncInternal<(RefParam<S>, $(OwnedParam<$T>,)*), R, VirtualMachine> for F
84101
where
85102
F: Fn(&S, $($T,)* &VirtualMachine) -> R + PyThreadingConstraint + 'static,
@@ -107,6 +124,20 @@ macro_rules! into_py_native_func_tuple {
107124
}
108125
}
109126

127+
impl<F, S, $($T,)* R> PyNativeFuncInternal<(BorrowedParam<S>, $(OwnedParam<$T>,)*), R, ()> for F
128+
where
129+
F: Fn(&Py<S>, $($T,)*) -> R + PyThreadingConstraint + 'static,
130+
S: PyPayload,
131+
$($T: FromArgs,)*
132+
R: ToPyResult,
133+
{
134+
fn call_(&self, vm: &VirtualMachine, args: FuncArgs) -> PyResult {
135+
let (zelf, $($n,)*) = args.bind::<(PyRef<S>, $($T,)*)>(vm)?;
136+
137+
(self)(&zelf, $($n,)*).to_pyresult(vm)
138+
}
139+
}
140+
110141
impl<F, S, $($T,)* R> PyNativeFuncInternal<(RefParam<S>, $(OwnedParam<$T>,)*), R, ()> for F
111142
where
112143
F: Fn(&S, $($T,)*) -> R + PyThreadingConstraint + 'static,

vm/src/function/getset.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
*/
44
use crate::{
55
convert::ToPyResult,
6-
function::{OwnedParam, RefParam},
6+
function::{BorrowedParam, OwnedParam, RefParam},
77
object::PyThreadingConstraint,
8-
PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
8+
Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
99
};
1010

1111
#[derive(result_like::OptionLike, is_macro::Is, Debug)]
@@ -74,6 +74,18 @@ where
7474
}
7575
}
7676

77+
impl<F, S, R> IntoPyGetterFunc<(BorrowedParam<S>, R, VirtualMachine)> for F
78+
where
79+
F: Fn(&Py<S>, &VirtualMachine) -> R + 'static + Send + Sync,
80+
S: PyPayload,
81+
R: ToPyResult,
82+
{
83+
fn get(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
84+
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
85+
(self)(&zelf, vm).to_pyresult(vm)
86+
}
87+
}
88+
7789
impl<F, S, R> IntoPyGetterFunc<(RefParam<S>, R, VirtualMachine)> for F
7890
where
7991
F: Fn(&S, &VirtualMachine) -> R + 'static + Send + Sync,
@@ -98,6 +110,18 @@ where
98110
}
99111
}
100112

113+
impl<F, S, R> IntoPyGetterFunc<(BorrowedParam<S>, R)> for F
114+
where
115+
F: Fn(&Py<S>) -> R + 'static + Send + Sync,
116+
S: PyPayload,
117+
R: ToPyResult,
118+
{
119+
fn get(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
120+
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
121+
(self)(&zelf).to_pyresult(vm)
122+
}
123+
}
124+
101125
impl<F, S, R> IntoPyGetterFunc<(RefParam<S>, R)> for F
102126
where
103127
F: Fn(&S) -> R + 'static + Send + Sync,
@@ -149,6 +173,20 @@ where
149173
}
150174
}
151175

176+
impl<F, S, V, R> IntoPySetterFunc<(BorrowedParam<S>, V, R, VirtualMachine)> for F
177+
where
178+
F: Fn(&Py<S>, V, &VirtualMachine) -> R + 'static + Send + Sync,
179+
S: PyPayload,
180+
V: FromPySetterValue,
181+
R: IntoPyNoResult,
182+
{
183+
fn set(&self, obj: PyObjectRef, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
184+
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
185+
let value = V::from_setter_value(vm, value)?;
186+
(self)(&zelf, value, vm).into_noresult()
187+
}
188+
}
189+
152190
impl<F, S, V, R> IntoPySetterFunc<(RefParam<S>, V, R, VirtualMachine)> for F
153191
where
154192
F: Fn(&S, V, &VirtualMachine) -> R + 'static + Send + Sync,
@@ -177,6 +215,20 @@ where
177215
}
178216
}
179217

218+
impl<F, S, V, R> IntoPySetterFunc<(BorrowedParam<S>, V, R)> for F
219+
where
220+
F: Fn(&Py<S>, V) -> R + 'static + Send + Sync,
221+
S: PyPayload,
222+
V: FromPySetterValue,
223+
R: IntoPyNoResult,
224+
{
225+
fn set(&self, obj: PyObjectRef, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
226+
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
227+
let value = V::from_setter_value(vm, value)?;
228+
(self)(&zelf, value).into_noresult()
229+
}
230+
}
231+
180232
impl<F, S, V, R> IntoPySetterFunc<(RefParam<S>, V, R)> for F
181233
where
182234
F: Fn(&S, V) -> R + 'static + Send + Sync,

vm/src/function/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ pub use argument::{
1313
};
1414
pub use arithmetic::{PyArithmeticValue, PyComparisonValue};
1515
pub use buffer::{ArgAsciiBuffer, ArgBytesLike, ArgMemoryBuffer, ArgStrOrBytesLike};
16-
pub use builtin::{IntoPyNativeFunc, OwnedParam, PyNativeFunc, RefParam};
16+
pub(self) use builtin::{BorrowedParam, OwnedParam, RefParam};
17+
pub use builtin::{IntoPyNativeFunc, PyNativeFunc};
1718
pub use either::Either;
1819
pub use getset::PySetterValue;
1920
pub(super) use getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetterFunc, PySetterFunc};

0 commit comments

Comments
 (0)