Allow first argument to be a shared ref to a python value

This commit is contained in:
Joey Hain committed 2019-04-06 18:50:40 -07:00
1 parent c6e875f209
commit be55562457
2 files changed
+32 -9

No files matched your search

+24 -3
View File
@@ -2,7 +2,9 @@ use std::collections::HashMap;
use std::ops::RangeInclusive;
use crate::obj::objtype::{isinstance, PyClassRef};
use crate::pyobject::{IntoPyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol};
use crate::pyobject::{
IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
};
use crate::vm::VirtualMachine;
use self::OptionalArg::*;
@@ -403,6 +405,7 @@ tuple_from_py_func_args!(A, B);
tuple_from_py_func_args!(A, B, C);
tuple_from_py_func_args!(A, B, C, D);
tuple_from_py_func_args!(A, B, C, D, E);
tuple_from_py_func_args!(A, B, C, D, E, F);
/// A built-in Python function.
pub type PyNativeFunc = Box<dyn Fn(&VirtualMachine, PyFuncArgs) -> PyResult + 'static>;
@@ -440,17 +443,19 @@ impl IntoPyNativeFunc<PyFuncArgs, PyResult> for PyNativeFunc {
}
}
pub struct OwnedParam<T>(std::marker::PhantomData<T>);
pub struct RefParam<T>(std::marker::PhantomData<T>);
// This is the "magic" that allows rust functions of varying signatures to
// generate native python functions.
//
// Note that this could be done without a macro - it is simply to avoid repetition.
macro_rules! into_py_native_func_tuple {
($(($n:tt, $T:ident)),*) => {
impl<F, $($T,)* R> IntoPyNativeFunc<($($T,)*), R> for F
impl<F, $($T,)* R> IntoPyNativeFunc<($(OwnedParam<$T>,)*), R> for F
where
F: Fn($($T,)* &VirtualMachine) -> R + 'static,
$($T: FromArgs,)*
($($T,)*): FromArgs,
R: IntoPyObject,
{
fn into_func(self) -> PyNativeFunc {
@@ -461,6 +466,22 @@ macro_rules! into_py_native_func_tuple {
})
}
}
impl<F, S, $($T,)* R> IntoPyNativeFunc<(RefParam<S>, $(OwnedParam<$T>,)*), R> for F
where
F: Fn(&S, $($T,)* &VirtualMachine) -> R + 'static,
S: PyValue,
$($T: FromArgs,)*
R: IntoPyObject,
{
fn into_func(self) -> PyNativeFunc {
Box::new(move |vm, args| {
let (zelf, $($n,)*) = args.bind::<(PyRef<S>, $($T,)*)>(vm)?;
(self)(&zelf, $($n,)* vm).into_pyobject(vm)
})
}
}
};
}
+8 -6
View File
@@ -34,6 +34,13 @@ impl From<f64> for PyFloat {
}
}
impl PyFloat {
fn is_integer(&self, _vm: &VirtualMachine) -> bool {
let v = self.value;
(v - v.round()).abs() < std::f64::EPSILON
}
}
pub type PyFloatRef = PyRef<PyFloat>;
impl PyFloatRef {
@@ -311,11 +318,6 @@ impl PyFloatRef {
}
}
fn is_integer(self, _vm: &VirtualMachine) -> bool {
let v = self.value;
(v - v.round()).abs() < std::f64::EPSILON
}
fn real(self, _vm: &VirtualMachine) -> Self {
self
}
@@ -385,7 +387,7 @@ pub fn init(context: &PyContext) {
"__mul__" => context.new_rustfunc(PyFloatRef::mul),
"__rmul__" => context.new_rustfunc(PyFloatRef::mul),
"real" => context.new_property(PyFloatRef::real),
"is_integer" => context.new_rustfunc(PyFloatRef::is_integer),
"is_integer" => context.new_rustfunc(PyFloat::is_integer),
"as_integer_ratio" => context.new_rustfunc(PyFloatRef::as_integer_ratio)
});
}