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