Refactor PyMethodDef creation too.
This commit is contained in:
parent
a8d2649032
commit
c670c57ddb
|
@ -544,7 +544,7 @@ impl<'a> FnSpec<'a> {
|
||||||
let rust_call = quote! { #rust_name(#(#arg_names),*) };
|
let rust_call = quote! { #rust_name(#(#arg_names),*) };
|
||||||
let arg_convert_and_rust_call = impl_arg_params(self, cls, rust_call, &py, false)?;
|
let arg_convert_and_rust_call = impl_arg_params(self, cls, rust_call, &py, false)?;
|
||||||
quote! {
|
quote! {
|
||||||
unsafe extern "C" fn __wrap(
|
unsafe extern "C" fn #ident (
|
||||||
subtype: *mut pyo3::ffi::PyTypeObject,
|
subtype: *mut pyo3::ffi::PyTypeObject,
|
||||||
_args: *mut pyo3::ffi::PyObject,
|
_args: *mut pyo3::ffi::PyObject,
|
||||||
_kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject
|
_kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject
|
||||||
|
@ -565,6 +565,37 @@ impl<'a> FnSpec<'a> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a `PyMethodDef` constructor for this function, matching the selected
|
||||||
|
/// calling convention.
|
||||||
|
pub fn get_methoddef(&self, wrapper: impl ToTokens) -> TokenStream {
|
||||||
|
let python_name = self.null_terminated_python_name();
|
||||||
|
let doc = &self.doc;
|
||||||
|
match self.convention {
|
||||||
|
CallingConvention::Noargs => quote! {
|
||||||
|
pyo3::class::methods::PyMethodDef::noargs(
|
||||||
|
#python_name,
|
||||||
|
pyo3::class::methods::PyCFunction(#wrapper),
|
||||||
|
#doc,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
CallingConvention::Fastcall => quote! {
|
||||||
|
pyo3::class::methods::PyMethodDef::fastcall_cfunction_with_keywords(
|
||||||
|
#python_name,
|
||||||
|
pyo3::class::methods::PyCFunctionFastWithKeywords(#wrapper),
|
||||||
|
#doc,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
CallingConvention::Varargs => quote! {
|
||||||
|
pyo3::class::methods::PyMethodDef::cfunction_with_keywords(
|
||||||
|
#python_name,
|
||||||
|
pyo3::class::methods::PyCFunctionWithKeywords(#wrapper),
|
||||||
|
#doc,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
CallingConvention::TpNew => unreachable!("tp_new cannot get a methoddef"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
|
|
@ -426,37 +426,16 @@ pub fn impl_wrap_pyfunction(
|
||||||
deprecations: options.deprecations,
|
deprecations: options.deprecations,
|
||||||
};
|
};
|
||||||
|
|
||||||
let doc = &spec.doc;
|
let wrapper_ident = format_ident!("__pyo3_raw_{}", spec.name);
|
||||||
let python_name = spec.null_terminated_python_name();
|
|
||||||
|
|
||||||
let name = &func.sig.ident;
|
|
||||||
let wrapper_ident = format_ident!("__pyo3_raw_{}", name);
|
|
||||||
let wrapper = spec.get_wrapper_function(&wrapper_ident, None)?;
|
let wrapper = spec.get_wrapper_function(&wrapper_ident, None)?;
|
||||||
let (methoddef_meth, cfunc_variant) = match spec.convention {
|
let methoddef = spec.get_methoddef(wrapper_ident);
|
||||||
CallingConvention::Noargs => (quote!(noargs), quote!(PyCFunction)),
|
|
||||||
CallingConvention::Fastcall => (
|
|
||||||
quote!(fastcall_cfunction_with_keywords),
|
|
||||||
quote!(PyCFunctionFastWithKeywords),
|
|
||||||
),
|
|
||||||
_ => (
|
|
||||||
quote!(cfunction_with_keywords),
|
|
||||||
quote!(PyCFunctionWithKeywords),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
let wrapped_pyfunction = quote! {
|
let wrapped_pyfunction = quote! {
|
||||||
#wrapper
|
#wrapper
|
||||||
pub(crate) fn #function_wrapper_ident<'a>(
|
pub(crate) fn #function_wrapper_ident<'a>(
|
||||||
args: impl Into<pyo3::derive_utils::PyFunctionArguments<'a>>
|
args: impl Into<pyo3::derive_utils::PyFunctionArguments<'a>>
|
||||||
) -> pyo3::PyResult<&'a pyo3::types::PyCFunction> {
|
) -> pyo3::PyResult<&'a pyo3::types::PyCFunction> {
|
||||||
pyo3::types::PyCFunction::internal_new(
|
pyo3::types::PyCFunction::internal_new(#methoddef, args.into())
|
||||||
pyo3::class::methods::PyMethodDef:: #methoddef_meth (
|
|
||||||
#python_name,
|
|
||||||
pyo3::class::methods:: #cfunc_variant (#wrapper_ident),
|
|
||||||
#doc,
|
|
||||||
),
|
|
||||||
args.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok((function_wrapper_ident, wrapped_pyfunction))
|
Ok((function_wrapper_ident, wrapped_pyfunction))
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::attributes::NameAttribute;
|
use crate::attributes::NameAttribute;
|
||||||
use crate::konst::ConstSpec;
|
use crate::konst::ConstSpec;
|
||||||
use crate::method::CallingConvention;
|
|
||||||
use crate::utils::ensure_not_async_fn;
|
use crate::utils::ensure_not_async_fn;
|
||||||
use crate::{deprecations::Deprecations, utils};
|
use crate::{deprecations::Deprecations, utils};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -250,36 +249,14 @@ pub fn impl_py_method_def(
|
||||||
let wrapper_ident = syn::Ident::new("__wrap", Span::call_site());
|
let wrapper_ident = syn::Ident::new("__wrap", Span::call_site());
|
||||||
let wrapper_def = spec.get_wrapper_function(&wrapper_ident, Some(cls))?;
|
let wrapper_def = spec.get_wrapper_function(&wrapper_ident, Some(cls))?;
|
||||||
let add_flags = flags.map(|flags| quote!(.flags(#flags)));
|
let add_flags = flags.map(|flags| quote!(.flags(#flags)));
|
||||||
let doc = &spec.doc;
|
|
||||||
let python_name = spec.null_terminated_python_name();
|
|
||||||
let methoddef_type = match spec.tp {
|
let methoddef_type = match spec.tp {
|
||||||
FnType::FnStatic => quote!(Static),
|
FnType::FnStatic => quote!(Static),
|
||||||
FnType::FnClass => quote!(Class),
|
FnType::FnClass => quote!(Class),
|
||||||
_ => quote!(Method),
|
_ => quote!(Method),
|
||||||
};
|
};
|
||||||
let (methoddef_meth, cfunc_variant) = match spec.convention {
|
let methoddef = spec.get_methoddef(quote! {{ #wrapper_def #wrapper_ident }});
|
||||||
CallingConvention::Noargs => (quote!(noargs), quote!(PyCFunction)),
|
|
||||||
CallingConvention::Fastcall => (
|
|
||||||
quote!(fastcall_cfunction_with_keywords),
|
|
||||||
quote!(PyCFunctionFastWithKeywords),
|
|
||||||
),
|
|
||||||
_ => (
|
|
||||||
quote!(cfunction_with_keywords),
|
|
||||||
quote!(PyCFunctionWithKeywords),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
pyo3::class::PyMethodDefType:: #methoddef_type ({
|
pyo3::class::PyMethodDefType::#methoddef_type(#methoddef #add_flags)
|
||||||
pyo3::class::PyMethodDef:: #methoddef_meth (
|
|
||||||
#python_name,
|
|
||||||
pyo3::class::methods:: #cfunc_variant ({
|
|
||||||
#wrapper_def
|
|
||||||
#wrapper_ident
|
|
||||||
}),
|
|
||||||
#doc
|
|
||||||
)
|
|
||||||
#add_flags
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue