mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 11:14:38 +08:00
Allow first argument to be a shared ref to a python value
This commit is contained in:
1 parent
c6e875f209
commit
be55562457
2 files changed
+32
-9
No files matched your search
+24
-3
@@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user