macros-backend: make __wrap fns expressions

This commit is contained in:
David Hewitt 2021-03-14 17:21:57 +00:00
parent 6ab61a1560
commit 3891788aa7
1 changed files with 37 additions and 48 deletions

View File

@ -75,11 +75,12 @@ pub fn gen_py_const(
) -> syn::Result<Option<TokenStream>> {
let spec = ConstSpec::parse(name, attrs)?;
if spec.is_class_attr {
let wrapper = quote! {
let wrapper = quote! {{
fn __wrap(py: pyo3::Python<'_>) -> pyo3::PyObject {
pyo3::IntoPy::into_py(#cls::#name, py)
}
};
__wrap
}};
return Ok(Some(impl_py_const_class_attribute(&spec, &wrapper)));
}
Ok(None)
@ -95,7 +96,7 @@ pub fn impl_wrap_cfunction_with_keywords(
let slf = self_ty.receiver(cls);
let python_name = &spec.python_name;
let body = impl_arg_params(&spec, Some(cls), body)?;
Ok(quote! {
Ok(quote! {{
unsafe extern "C" fn __wrap(
_slf: *mut pyo3::ffi::PyObject,
_args: *mut pyo3::ffi::PyObject,
@ -111,7 +112,8 @@ pub fn impl_wrap_cfunction_with_keywords(
#body
})
}
})
__wrap
}})
}
/// Generate function wrapper PyCFunction
@ -120,7 +122,7 @@ pub fn impl_wrap_noargs(cls: &syn::Type, spec: &FnSpec<'_>, self_ty: &SelfType)
let slf = self_ty.receiver(cls);
let python_name = &spec.python_name;
assert!(spec.args.is_empty());
quote! {
quote! {{
unsafe extern "C" fn __wrap(
_slf: *mut pyo3::ffi::PyObject,
_args: *mut pyo3::ffi::PyObject,
@ -133,7 +135,8 @@ pub fn impl_wrap_noargs(cls: &syn::Type, spec: &FnSpec<'_>, self_ty: &SelfType)
#body
})
}
}
__wrap
}}
}
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
@ -144,7 +147,7 @@ pub fn impl_wrap_new(cls: &syn::Type, spec: &FnSpec<'_>) -> Result<TokenStream>
let cb = quote! { #cls::#name(#(#names),*) };
let body = impl_arg_params(spec, Some(cls), cb)?;
Ok(quote! {
Ok(quote! {{
#[allow(unused_mut)]
unsafe extern "C" fn __wrap(
subtype: *mut pyo3::ffi::PyTypeObject,
@ -163,7 +166,8 @@ pub fn impl_wrap_new(cls: &syn::Type, spec: &FnSpec<'_>) -> Result<TokenStream>
Ok(cell as *mut pyo3::ffi::PyObject)
})
}
})
__wrap
}})
}
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
@ -175,7 +179,7 @@ pub fn impl_wrap_class(cls: &syn::Type, spec: &FnSpec<'_>) -> Result<TokenStream
let body = impl_arg_params(spec, Some(cls), cb)?;
Ok(quote! {
Ok(quote! {{
#[allow(unused_mut)]
unsafe extern "C" fn __wrap(
_cls: *mut pyo3::ffi::PyObject,
@ -191,7 +195,8 @@ pub fn impl_wrap_class(cls: &syn::Type, spec: &FnSpec<'_>) -> Result<TokenStream
#body
})
}
})
__wrap
}})
}
/// Generate static method wrapper (PyCFunction, PyCFunctionWithKeywords)
@ -203,7 +208,7 @@ pub fn impl_wrap_static(cls: &syn::Type, spec: &FnSpec<'_>) -> Result<TokenStrea
let body = impl_arg_params(spec, Some(cls), cb)?;
Ok(quote! {
Ok(quote! {{
#[allow(unused_mut)]
unsafe extern "C" fn __wrap(
_slf: *mut pyo3::ffi::PyObject,
@ -218,7 +223,8 @@ pub fn impl_wrap_static(cls: &syn::Type, spec: &FnSpec<'_>) -> Result<TokenStrea
#body
})
}
})
__wrap
}})
}
/// Generate a wrapper for initialization of a class attribute from a method
@ -228,11 +234,12 @@ pub fn impl_wrap_class_attribute(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStr
let name = &spec.name;
let cb = quote! { #cls::#name() };
quote! {
quote! {{
fn __wrap(py: pyo3::Python<'_>) -> pyo3::PyObject {
pyo3::IntoPy::into_py(#cb, py)
}
}
__wrap
}}
}
fn impl_call_getter(cls: &syn::Type, spec: &FnSpec) -> syn::Result<TokenStream> {
@ -272,7 +279,7 @@ pub(crate) fn impl_wrap_getter(
};
let slf = self_ty.receiver(cls);
Ok(quote! {
Ok(quote! {{
unsafe extern "C" fn __wrap(
_slf: *mut pyo3::ffi::PyObject, _: *mut std::os::raw::c_void) -> *mut pyo3::ffi::PyObject
{
@ -282,7 +289,8 @@ pub(crate) fn impl_wrap_getter(
pyo3::callback::convert(_py, #getter_impl)
})
}
})
__wrap
}})
}
fn impl_call_setter(cls: &syn::Type, spec: &FnSpec) -> syn::Result<TokenStream> {
@ -322,7 +330,7 @@ pub(crate) fn impl_wrap_setter(
};
let slf = self_ty.receiver(cls);
Ok(quote! {
Ok(quote! {{
#[allow(unused_mut)]
unsafe extern "C" fn __wrap(
_slf: *mut pyo3::ffi::PyObject,
@ -337,7 +345,8 @@ pub(crate) fn impl_wrap_setter(
pyo3::callback::convert(_py, #setter_impl)
})
}
})
__wrap
}})
}
/// This function abstracts away some copied code and can propably be simplified itself
@ -576,11 +585,9 @@ pub fn impl_py_method_def(
let wrapper = impl_wrap_noargs(cls, spec, self_ty);
Ok(quote! {
pyo3::class::PyMethodDefType::Method({
#wrapper
pyo3::class::PyMethodDef::noargs(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PyCFunction(__wrap),
pyo3::class::methods::PyCFunction(#wrapper),
#doc
)
#add_flags
@ -591,11 +598,9 @@ pub fn impl_py_method_def(
let wrapper = impl_wrap_cfunction_with_keywords(cls, &spec, self_ty)?;
Ok(quote! {
pyo3::class::PyMethodDefType::Method({
#wrapper
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PyCFunctionWithKeywords(__wrap),
pyo3::class::methods::PyCFunctionWithKeywords(#wrapper),
#doc
)
#add_flags
@ -609,9 +614,7 @@ pub fn impl_py_method_def_new(cls: &syn::Type, spec: &FnSpec) -> Result<TokenStr
Ok(quote! {
impl pyo3::class::impl_::PyClassNewImpl<#cls> for pyo3::class::impl_::PyClassImplCollector<#cls> {
fn new_impl(self) -> Option<pyo3::ffi::newfunc> {
#wrapper
Some(__wrap)
Some(#wrapper)
}
}
})
@ -623,11 +626,9 @@ pub fn impl_py_method_def_class(cls: &syn::Type, spec: &FnSpec) -> Result<TokenS
let doc = &spec.doc;
Ok(quote! {
pyo3::class::PyMethodDefType::Class({
#wrapper
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PyCFunctionWithKeywords(__wrap),
pyo3::class::methods::PyCFunctionWithKeywords(#wrapper),
#doc
).flags(pyo3::ffi::METH_CLASS)
})
@ -640,11 +641,9 @@ pub fn impl_py_method_def_static(cls: &syn::Type, spec: &FnSpec) -> Result<Token
let doc = &spec.doc;
Ok(quote! {
pyo3::class::PyMethodDefType::Static({
#wrapper
pyo3::class::PyMethodDef::cfunction_with_keywords(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PyCFunctionWithKeywords(__wrap),
pyo3::class::methods::PyCFunctionWithKeywords(#wrapper),
#doc
).flags(pyo3::ffi::METH_STATIC)
})
@ -656,11 +655,9 @@ pub fn impl_py_method_class_attribute(cls: &syn::Type, spec: &FnSpec) -> TokenSt
let python_name = &spec.python_name;
quote! {
pyo3::class::PyMethodDefType::ClassAttribute({
#wrapper
pyo3::class::PyClassAttributeDef::new(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PyClassAttributeFactory(__wrap)
pyo3::class::methods::PyClassAttributeFactory(#wrapper)
)
})
}
@ -670,11 +667,9 @@ pub fn impl_py_const_class_attribute(spec: &ConstSpec, wrapper: &TokenStream) ->
let python_name = &spec.python_name;
quote! {
pyo3::class::PyMethodDefType::ClassAttribute({
#wrapper
pyo3::class::PyClassAttributeDef::new(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PyClassAttributeFactory(__wrap)
pyo3::class::methods::PyClassAttributeFactory(#wrapper)
)
})
}
@ -689,9 +684,7 @@ pub fn impl_py_method_def_call(
Ok(quote! {
impl pyo3::class::impl_::PyClassCallImpl<#cls> for pyo3::class::impl_::PyClassImplCollector<#cls> {
fn call_impl(self) -> Option<pyo3::ffi::PyCFunctionWithKeywords> {
#wrapper
Some(__wrap)
Some(#wrapper)
}
}
})
@ -707,11 +700,9 @@ pub(crate) fn impl_py_setter_def(
let wrapper = impl_wrap_setter(cls, property_type, self_ty)?;
Ok(quote! {
pyo3::class::PyMethodDefType::Setter({
#wrapper
pyo3::class::PySetterDef::new(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PySetter(__wrap),
pyo3::class::methods::PySetter(#wrapper),
#doc
)
})
@ -728,11 +719,9 @@ pub(crate) fn impl_py_getter_def(
let wrapper = impl_wrap_getter(cls, property_type, self_ty)?;
Ok(quote! {
pyo3::class::PyMethodDefType::Getter({
#wrapper
pyo3::class::PyGetterDef::new(
concat!(stringify!(#python_name), "\0"),
pyo3::class::methods::PyGetter(__wrap),
pyo3::class::methods::PyGetter(#wrapper),
#doc
)
})