2017-05-16 05:24:06 +00:00
|
|
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
2019-03-29 09:57:05 +00:00
|
|
|
use crate::method::{FnArg, FnSpec, FnType};
|
2019-02-01 13:01:18 +00:00
|
|
|
use crate::utils;
|
|
|
|
use proc_macro2::{Span, TokenStream};
|
|
|
|
use quote::quote;
|
2017-05-18 07:05:49 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
pub fn gen_py_method(
|
2018-05-14 11:04:29 +00:00
|
|
|
cls: &syn::Type,
|
2018-05-13 19:24:40 +00:00
|
|
|
name: &syn::Ident,
|
|
|
|
sig: &mut syn::MethodSig,
|
2018-07-03 20:28:40 +00:00
|
|
|
meth_attrs: &mut Vec<syn::Attribute>,
|
2018-06-15 20:41:16 +00:00
|
|
|
) -> TokenStream {
|
2017-05-16 05:24:06 +00:00
|
|
|
check_generic(name, sig);
|
|
|
|
|
2017-06-18 15:00:27 +00:00
|
|
|
let doc = utils::get_doc(&meth_attrs, true);
|
2019-02-18 19:07:41 +00:00
|
|
|
let spec = FnSpec::parse(name, sig, meth_attrs).unwrap();
|
2017-05-16 05:24:06 +00:00
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
match spec.tp {
|
2018-07-03 20:28:40 +00:00
|
|
|
FnType::Fn => impl_py_method_def(name, doc, &spec, &impl_wrap(cls, name, &spec, true)),
|
2019-03-29 09:57:05 +00:00
|
|
|
FnType::PySelf(ref self_ty) => impl_py_method_def(
|
2019-03-28 13:55:41 +00:00
|
|
|
name,
|
|
|
|
doc,
|
|
|
|
&spec,
|
2019-03-29 09:57:05 +00:00
|
|
|
&impl_wrap_pyslf(cls, name, &spec, self_ty, true),
|
2019-03-28 13:55:41 +00:00
|
|
|
),
|
2018-07-03 20:28:40 +00:00
|
|
|
FnType::FnNew => impl_py_method_def_new(name, doc, &impl_wrap_new(cls, name, &spec)),
|
|
|
|
FnType::FnInit => impl_py_method_def_init(name, doc, &impl_wrap_init(cls, name, &spec)),
|
|
|
|
FnType::FnCall => impl_py_method_def_call(name, doc, &impl_wrap(cls, name, &spec, false)),
|
|
|
|
FnType::FnClass => impl_py_method_def_class(name, doc, &impl_wrap_class(cls, name, &spec)),
|
|
|
|
FnType::FnStatic => {
|
|
|
|
impl_py_method_def_static(name, doc, &impl_wrap_static(cls, name, &spec))
|
|
|
|
}
|
|
|
|
FnType::Getter(ref getter) => {
|
|
|
|
impl_py_getter_def(name, doc, getter, &impl_wrap_getter(cls, name))
|
|
|
|
}
|
|
|
|
FnType::Setter(ref setter) => {
|
|
|
|
impl_py_setter_def(name, doc, setter, &impl_wrap_setter(cls, name, &spec))
|
|
|
|
}
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-16 18:58:18 +00:00
|
|
|
fn check_generic(name: &syn::Ident, sig: &syn::MethodSig) {
|
2018-05-13 19:24:40 +00:00
|
|
|
if !sig.decl.generics.params.is_empty() {
|
2017-05-16 05:24:06 +00:00
|
|
|
panic!("python method can not be generic: {:?}", name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
/// Generate function wrapper (PyCFunction, PyCFunctionWithKeywords)
|
2019-02-01 13:01:18 +00:00
|
|
|
pub fn impl_wrap(
|
|
|
|
cls: &syn::Type,
|
|
|
|
name: &syn::Ident,
|
|
|
|
spec: &FnSpec<'_>,
|
|
|
|
noargs: bool,
|
|
|
|
) -> TokenStream {
|
2018-04-06 15:19:32 +00:00
|
|
|
let body = impl_call(cls, name, &spec);
|
2019-04-03 08:14:03 +00:00
|
|
|
let slf = impl_self("e! { &mut #cls });
|
2019-03-28 13:55:41 +00:00
|
|
|
impl_wrap_common(cls, name, spec, noargs, slf, body)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn impl_wrap_pyslf(
|
|
|
|
cls: &syn::Type,
|
|
|
|
name: &syn::Ident,
|
|
|
|
spec: &FnSpec<'_>,
|
2019-04-03 08:14:03 +00:00
|
|
|
self_ty: &syn::TypePath,
|
2019-03-28 13:55:41 +00:00
|
|
|
noargs: bool,
|
|
|
|
) -> TokenStream {
|
|
|
|
let names = get_arg_names(spec);
|
|
|
|
let body = quote! {
|
|
|
|
#cls::#name(_slf, #(#names),*)
|
|
|
|
};
|
2019-04-03 08:14:03 +00:00
|
|
|
let slf = impl_self(self_ty);
|
2019-03-28 13:55:41 +00:00
|
|
|
impl_wrap_common(cls, name, spec, noargs, slf, body)
|
|
|
|
}
|
2017-05-20 06:14:59 +00:00
|
|
|
|
2019-03-28 13:55:41 +00:00
|
|
|
fn impl_wrap_common(
|
|
|
|
cls: &syn::Type,
|
|
|
|
name: &syn::Ident,
|
|
|
|
spec: &FnSpec<'_>,
|
|
|
|
noargs: bool,
|
|
|
|
slf: TokenStream,
|
|
|
|
body: TokenStream,
|
|
|
|
) -> TokenStream {
|
2017-06-07 04:57:03 +00:00
|
|
|
if spec.args.is_empty() && noargs {
|
|
|
|
quote! {
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_slf: *mut pyo3::ffi::PyObject
|
|
|
|
) -> *mut pyo3::ffi::PyObject
|
2017-06-07 04:57:03 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(
|
2017-06-07 04:57:03 +00:00
|
|
|
stringify!(#cls), ".", stringify!(#name), "()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
2019-03-28 13:55:41 +00:00
|
|
|
#slf
|
2019-02-18 19:07:41 +00:00
|
|
|
let _result = {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::derive_utils::IntoPyResult::into_py_result(#body)
|
2019-02-18 19:07:41 +00:00
|
|
|
};
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::callback::cb_convert(
|
|
|
|
pyo3::callback::PyObjectCallbackConverter, _py, _result)
|
2017-06-07 04:57:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2018-04-06 15:19:32 +00:00
|
|
|
let body = impl_arg_params(&spec, body);
|
2017-05-20 06:14:59 +00:00
|
|
|
|
2017-06-07 04:57:03 +00:00
|
|
|
quote! {
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_slf: *mut pyo3::ffi::PyObject,
|
|
|
|
_args: *mut pyo3::ffi::PyObject,
|
|
|
|
_kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject
|
2017-06-07 04:57:03 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(
|
2017-06-07 04:57:03 +00:00
|
|
|
stringify!(#cls), ".", stringify!(#name), "()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
2019-03-28 13:55:41 +00:00
|
|
|
#slf
|
2019-03-16 10:40:56 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
|
|
|
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
#body
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::callback::cb_convert(
|
|
|
|
pyo3::callback::PyObjectCallbackConverter, _py, _result)
|
2017-06-07 04:57:03 +00:00
|
|
|
}
|
2017-05-20 06:14:59 +00:00
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-25 05:43:07 +00:00
|
|
|
/// Generate function wrapper for protocol method (PyCFunction, PyCFunctionWithKeywords)
|
2019-02-01 13:01:18 +00:00
|
|
|
pub fn impl_proto_wrap(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
2017-05-25 05:43:07 +00:00
|
|
|
let cb = impl_call(cls, name, &spec);
|
|
|
|
let body = impl_arg_params(&spec, cb);
|
|
|
|
|
|
|
|
quote! {
|
2017-05-27 17:49:38 +00:00
|
|
|
#[allow(unused_mut)]
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_slf: *mut pyo3::ffi::PyObject,
|
|
|
|
_args: *mut pyo3::ffi::PyObject,
|
|
|
|
_kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject
|
2017-05-25 05:43:07 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
2017-08-01 21:29:25 +00:00
|
|
|
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
|
2019-03-16 10:40:56 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
|
|
|
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
#body
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::callback::cb_convert(
|
|
|
|
pyo3::callback::PyObjectCallbackConverter, _py, _result)
|
2017-05-25 05:43:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-20 06:14:59 +00:00
|
|
|
|
2017-06-08 18:29:40 +00:00
|
|
|
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
|
2019-02-01 13:01:18 +00:00
|
|
|
pub fn impl_wrap_new(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
let names: Vec<syn::Ident> = get_arg_names(&spec);
|
|
|
|
let cb = quote! { #cls::#name(&_obj, #(#names),*) };
|
2017-06-08 18:29:40 +00:00
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
let body = impl_arg_params(spec, cb);
|
2017-05-16 05:24:06 +00:00
|
|
|
|
|
|
|
quote! {
|
2017-05-27 17:49:38 +00:00
|
|
|
#[allow(unused_mut)]
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_cls: *mut pyo3::ffi::PyTypeObject,
|
|
|
|
_args: *mut pyo3::ffi::PyObject,
|
|
|
|
_kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject
|
2017-05-16 05:24:06 +00:00
|
|
|
{
|
2019-03-16 10:40:56 +00:00
|
|
|
use pyo3::type_object::PyTypeInfo;
|
2017-08-08 07:27:33 +00:00
|
|
|
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
|
|
|
match pyo3::type_object::PyRawObject::new(_py, #cls::type_object(), _cls) {
|
2017-08-08 07:27:33 +00:00
|
|
|
Ok(_obj) => {
|
2019-03-16 10:40:56 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
|
|
|
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
2017-08-08 07:27:33 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
#body
|
2017-08-08 07:27:33 +00:00
|
|
|
|
|
|
|
match _result {
|
2019-03-16 10:40:56 +00:00
|
|
|
Ok(_) => pyo3::IntoPyPointer::into_ptr(_obj),
|
2017-08-08 07:27:33 +00:00
|
|
|
Err(e) => {
|
2017-08-08 07:58:12 +00:00
|
|
|
e.restore(_py);
|
2018-07-03 19:11:56 +00:00
|
|
|
::std::ptr::null_mut()
|
2017-08-08 07:27:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(e) => {
|
2017-08-08 07:58:12 +00:00
|
|
|
e.restore(_py);
|
2018-07-03 19:11:56 +00:00
|
|
|
::std::ptr::null_mut()
|
2017-08-08 07:27:33 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-27 23:14:54 +00:00
|
|
|
/// Generate function wrapper for ffi::initproc
|
2019-02-01 13:01:18 +00:00
|
|
|
fn impl_wrap_init(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
2017-07-27 23:14:54 +00:00
|
|
|
let cb = impl_call(cls, name, &spec);
|
2018-04-06 15:19:32 +00:00
|
|
|
let output = &spec.output;
|
2019-02-01 13:01:18 +00:00
|
|
|
let result_empty: syn::Type = syn::parse_quote!(PyResult<()>);
|
|
|
|
let empty: syn::Type = syn::parse_quote!(());
|
2018-06-15 20:41:16 +00:00
|
|
|
if output != &result_empty || output != &empty {
|
2018-04-06 15:19:32 +00:00
|
|
|
panic!("Constructor must return PyResult<()> or a ()");
|
|
|
|
}
|
|
|
|
|
2017-07-27 23:14:54 +00:00
|
|
|
let body = impl_arg_params(&spec, cb);
|
|
|
|
|
|
|
|
quote! {
|
|
|
|
#[allow(unused_mut)]
|
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_slf: *mut pyo3::ffi::PyObject,
|
|
|
|
_args: *mut pyo3::ffi::PyObject,
|
2019-04-17 17:06:12 +00:00
|
|
|
_kwargs: *mut pyo3::ffi::PyObject) -> pyo3::libc::c_int
|
2017-07-27 23:14:54 +00:00
|
|
|
{
|
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
2017-08-01 21:29:25 +00:00
|
|
|
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
|
2019-03-16 10:40:56 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
|
|
|
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
2017-07-27 23:14:54 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
#body
|
|
|
|
|
2017-07-27 23:14:54 +00:00
|
|
|
match _result {
|
|
|
|
Ok(_) => 0,
|
|
|
|
Err(e) => {
|
|
|
|
e.restore(_py);
|
|
|
|
-1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-08 18:29:40 +00:00
|
|
|
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
|
2019-02-01 13:01:18 +00:00
|
|
|
pub fn impl_wrap_class(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
let names: Vec<syn::Ident> = get_arg_names(&spec);
|
|
|
|
let cb = quote! { #cls::#name(&_cls, #(#names),*) };
|
2018-04-06 15:19:32 +00:00
|
|
|
|
2017-06-08 18:29:40 +00:00
|
|
|
let body = impl_arg_params(spec, cb);
|
|
|
|
|
|
|
|
quote! {
|
|
|
|
#[allow(unused_mut)]
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_cls: *mut pyo3::ffi::PyObject,
|
|
|
|
_args: *mut pyo3::ffi::PyObject,
|
|
|
|
_kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject
|
2017-06-08 18:29:40 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
|
|
|
let _cls = pyo3::types::PyType::from_type_ptr(_py, _cls as *mut pyo3::ffi::PyTypeObject);
|
|
|
|
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
|
|
|
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
#body
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::callback::cb_convert(
|
|
|
|
pyo3::callback::PyObjectCallbackConverter, _py, _result)
|
2017-06-08 18:29:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Generate static method wrapper (PyCFunction, PyCFunctionWithKeywords)
|
2019-02-01 13:01:18 +00:00
|
|
|
pub fn impl_wrap_static(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
let names: Vec<syn::Ident> = get_arg_names(&spec);
|
|
|
|
let cb = quote! { #cls::#name(#(#names),*) };
|
2017-06-08 18:29:40 +00:00
|
|
|
|
|
|
|
let body = impl_arg_params(spec, cb);
|
|
|
|
|
|
|
|
quote! {
|
|
|
|
#[allow(unused_mut)]
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_slf: *mut pyo3::ffi::PyObject,
|
|
|
|
_args: *mut pyo3::ffi::PyObject,
|
|
|
|
_kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject
|
2017-06-08 18:29:40 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
|
|
|
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
|
|
|
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
2017-06-08 18:29:40 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
#body
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::callback::cb_convert(
|
|
|
|
pyo3::callback::PyObjectCallbackConverter, _py, _result)
|
2017-06-08 18:29:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-16 18:58:18 +00:00
|
|
|
|
|
|
|
/// Generate functiona wrapper (PyCFunction, PyCFunctionWithKeywords)
|
2018-06-15 20:41:16 +00:00
|
|
|
pub(crate) fn impl_wrap_getter(cls: &syn::Type, name: &syn::Ident) -> TokenStream {
|
2017-05-16 18:58:18 +00:00
|
|
|
quote! {
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_slf: *mut pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> *mut pyo3::ffi::PyObject
|
2017-05-16 18:58:18 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
2017-08-01 21:29:25 +00:00
|
|
|
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2019-04-17 18:55:57 +00:00
|
|
|
let result = pyo3::derive_utils::IntoPyResult::into_py_result(_slf.#name());
|
|
|
|
|
|
|
|
match result {
|
2017-07-20 21:21:57 +00:00
|
|
|
Ok(val) => {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::IntoPyPointer::into_ptr(val.into_object(_py))
|
2017-07-20 21:21:57 +00:00
|
|
|
}
|
|
|
|
Err(e) => {
|
2017-07-23 17:07:23 +00:00
|
|
|
e.restore(_py);
|
2018-07-03 19:11:56 +00:00
|
|
|
::std::ptr::null_mut()
|
2017-07-20 21:21:57 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-16 18:58:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Generate functiona wrapper (PyCFunction, PyCFunctionWithKeywords)
|
2019-02-01 13:01:18 +00:00
|
|
|
pub(crate) fn impl_wrap_setter(
|
|
|
|
cls: &syn::Type,
|
|
|
|
name: &syn::Ident,
|
|
|
|
spec: &FnSpec<'_>,
|
|
|
|
) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
if spec.args.is_empty() {
|
2019-01-08 19:18:06 +00:00
|
|
|
println!(
|
|
|
|
"Not enough arguments for setter {}::{}",
|
|
|
|
quote! {#cls},
|
|
|
|
name
|
|
|
|
);
|
2017-05-27 17:49:38 +00:00
|
|
|
}
|
2017-05-20 06:14:59 +00:00
|
|
|
let val_ty = spec.args[0].ty;
|
2017-05-18 21:46:29 +00:00
|
|
|
|
2017-05-16 18:58:18 +00:00
|
|
|
quote! {
|
2017-05-27 17:49:38 +00:00
|
|
|
#[allow(unused_mut)]
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2019-03-16 10:40:56 +00:00
|
|
|
_slf: *mut pyo3::ffi::PyObject,
|
2019-04-17 17:06:12 +00:00
|
|
|
_value: *mut pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> pyo3::libc::c_int
|
2017-05-16 18:58:18 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2019-03-16 10:40:56 +00:00
|
|
|
let _pool = pyo3::GILPool::new();
|
|
|
|
let _py = pyo3::Python::assume_gil_acquired();
|
2017-08-01 21:29:25 +00:00
|
|
|
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
|
|
|
|
let _value = _py.from_borrowed_ptr(_value);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
let _result = match <#val_ty as pyo3::FromPyObject>::extract(_value) {
|
2019-04-17 18:55:57 +00:00
|
|
|
Ok(_val) => {
|
|
|
|
pyo3::derive_utils::IntoPyResult::into_py_result(_slf.#name(_val))
|
|
|
|
}
|
2017-07-20 21:21:57 +00:00
|
|
|
Err(e) => Err(e)
|
|
|
|
};
|
2017-07-23 17:07:23 +00:00
|
|
|
match _result {
|
2017-07-20 21:21:57 +00:00
|
|
|
Ok(_) => 0,
|
|
|
|
Err(e) => {
|
2017-07-23 17:07:23 +00:00
|
|
|
e.restore(_py);
|
2017-07-20 21:21:57 +00:00
|
|
|
-1
|
2017-05-25 05:43:07 +00:00
|
|
|
}
|
2017-07-20 21:21:57 +00:00
|
|
|
}
|
2017-05-16 18:58:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
/// This function abstracts away some copied code and can propably be simplified itself
|
|
|
|
pub fn get_arg_names(spec: &FnSpec) -> Vec<syn::Ident> {
|
|
|
|
spec.args
|
2018-07-03 20:28:40 +00:00
|
|
|
.iter()
|
|
|
|
.enumerate()
|
2019-02-18 19:07:41 +00:00
|
|
|
.map(|(pos, _)| syn::Ident::new(&format!("arg{}", pos), Span::call_site()))
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn impl_call(_cls: &syn::Type, fname: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
|
|
|
let names = get_arg_names(spec);
|
|
|
|
quote! { _slf.#fname(#(#names),*) }
|
|
|
|
}
|
|
|
|
|
2019-04-03 08:14:03 +00:00
|
|
|
fn impl_self<T: quote::ToTokens>(self_ty: &T) -> TokenStream {
|
|
|
|
quote! {
|
|
|
|
let _slf: #self_ty = pyo3::FromPyPointer::from_borrowed_ptr(_py, _slf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
/// Converts a bool to "true" or "false"
|
|
|
|
fn bool_to_ident(condition: bool) -> syn::Ident {
|
|
|
|
if condition {
|
|
|
|
syn::Ident::new("true", Span::call_site())
|
|
|
|
} else {
|
|
|
|
syn::Ident::new("false", Span::call_site())
|
2018-04-12 21:20:35 +00:00
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-01 13:01:18 +00:00
|
|
|
pub fn impl_arg_params(spec: &FnSpec<'_>, body: TokenStream) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
if spec.args.is_empty() {
|
|
|
|
return quote! {
|
|
|
|
let _result = {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::derive_utils::IntoPyResult::into_py_result(#body)
|
2019-02-18 19:07:41 +00:00
|
|
|
};
|
|
|
|
};
|
2017-05-25 05:43:07 +00:00
|
|
|
}
|
2017-06-18 15:00:27 +00:00
|
|
|
|
2017-05-16 05:24:06 +00:00
|
|
|
let mut params = Vec::new();
|
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
for arg in spec.args.iter() {
|
2019-02-18 19:07:41 +00:00
|
|
|
if arg.py || spec.is_args(&arg.name) || spec.is_kwargs(&arg.name) {
|
2018-07-03 20:28:40 +00:00
|
|
|
continue;
|
2017-06-22 19:32:01 +00:00
|
|
|
}
|
2019-02-18 19:07:41 +00:00
|
|
|
let name = arg.name;
|
|
|
|
let kwonly = bool_to_ident(spec.is_kw_only(&arg.name));
|
|
|
|
let opt = bool_to_ident(arg.optional.is_some() || spec.default_value(&arg.name).is_some());
|
|
|
|
|
|
|
|
params.push(quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::derive_utils::ParamDescription {
|
2019-02-18 19:07:41 +00:00
|
|
|
name: stringify!(#name),
|
|
|
|
is_optional: #opt,
|
|
|
|
kw_only: #kwonly
|
|
|
|
}
|
|
|
|
});
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
2018-07-03 20:28:40 +00:00
|
|
|
let placeholders: Vec<syn::Ident> = params
|
|
|
|
.iter()
|
|
|
|
.map(|_| syn::Ident::new("None", Span::call_site()))
|
|
|
|
.collect();
|
2017-05-16 05:24:06 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
let mut param_conversion = Vec::new();
|
|
|
|
let mut option_pos = 0;
|
|
|
|
for (idx, arg) in spec.args.iter().enumerate() {
|
|
|
|
param_conversion.push(impl_arg_param(&arg, &spec, idx, &mut option_pos));
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
let accept_args = bool_to_ident(spec.accept_args());
|
|
|
|
let accept_kwargs = bool_to_ident(spec.accept_kwargs());
|
2017-05-18 07:05:49 +00:00
|
|
|
|
2017-05-16 05:24:06 +00:00
|
|
|
// create array of arguments, and then parse
|
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
use pyo3::ObjectProtocol;
|
|
|
|
const PARAMS: &'static [pyo3::derive_utils::ParamDescription] = &[
|
2017-05-16 05:24:06 +00:00
|
|
|
#(#params),*
|
|
|
|
];
|
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
let mut output = [#(#placeholders),*];
|
2017-05-16 05:24:06 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
// Workaround to use the question mark operator without rewriting everything
|
|
|
|
let _result = (|| {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::derive_utils::parse_fn_args(
|
2019-02-18 19:07:41 +00:00
|
|
|
Some(_LOCATION),
|
|
|
|
PARAMS,
|
|
|
|
&_args,
|
|
|
|
_kwargs,
|
|
|
|
#accept_args,
|
|
|
|
#accept_kwargs,
|
|
|
|
&mut output
|
|
|
|
)?;
|
|
|
|
|
|
|
|
#(#param_conversion)*
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::derive_utils::IntoPyResult::into_py_result(#body)
|
2019-02-18 19:07:41 +00:00
|
|
|
})();
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
/// Re option_pos: The option slice doesn't contain the py: Python argument, so the argument
|
|
|
|
/// index and the index in option diverge when using py: Python
|
2019-02-01 13:01:18 +00:00
|
|
|
fn impl_arg_param(
|
|
|
|
arg: &FnArg<'_>,
|
|
|
|
spec: &FnSpec<'_>,
|
|
|
|
idx: usize,
|
2019-02-18 19:07:41 +00:00
|
|
|
option_pos: &mut usize,
|
2019-02-01 13:01:18 +00:00
|
|
|
) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
let arg_name = syn::Ident::new(&format!("arg{}", idx), Span::call_site());
|
|
|
|
|
2017-06-22 19:32:01 +00:00
|
|
|
if arg.py {
|
2019-02-18 19:07:41 +00:00
|
|
|
return quote! {
|
|
|
|
let #arg_name = _py;
|
|
|
|
};
|
2017-06-22 19:32:01 +00:00
|
|
|
}
|
2019-02-18 19:07:41 +00:00
|
|
|
let arg_value = quote!(output[#option_pos]);
|
|
|
|
*option_pos += 1;
|
|
|
|
|
2017-05-16 05:24:06 +00:00
|
|
|
let ty = arg.ty;
|
|
|
|
let name = arg.name;
|
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
if spec.is_args(&name) {
|
2017-05-16 05:24:06 +00:00
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
let #arg_name = <#ty as pyo3::FromPyObject>::extract(_args.as_ref())?;
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
2018-04-06 15:19:32 +00:00
|
|
|
} else if spec.is_kwargs(&name) {
|
2019-02-18 19:07:41 +00:00
|
|
|
quote! {
|
2017-07-23 17:07:23 +00:00
|
|
|
let #arg_name = _kwargs;
|
2019-02-18 19:07:41 +00:00
|
|
|
}
|
|
|
|
} else if arg.optional.is_some() {
|
|
|
|
let default = if let Some(d) = spec.default_value(name) {
|
|
|
|
quote! { Some(#d) }
|
|
|
|
} else {
|
|
|
|
quote! { None }
|
|
|
|
};
|
2017-06-14 05:37:26 +00:00
|
|
|
|
2019-02-18 19:07:41 +00:00
|
|
|
quote! {
|
|
|
|
let #arg_name = match #arg_value.as_ref() {
|
|
|
|
Some(_obj) => {
|
|
|
|
if _obj.is_none() {
|
|
|
|
#default
|
|
|
|
} else {
|
|
|
|
Some(_obj.extract()?)
|
2018-05-14 20:44:30 +00:00
|
|
|
}
|
2019-02-18 19:07:41 +00:00
|
|
|
},
|
|
|
|
None => #default
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} else if let Some(default) = spec.default_value(name) {
|
|
|
|
quote! {
|
|
|
|
let #arg_name = match #arg_value.as_ref() {
|
|
|
|
Some(_obj) => {
|
|
|
|
if _obj.is_none() {
|
|
|
|
#default
|
|
|
|
} else {
|
|
|
|
_obj.extract()?
|
|
|
|
}
|
|
|
|
},
|
|
|
|
None => #default
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
quote! {
|
|
|
|
let #arg_name = #arg_value.unwrap().extract()?;
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub fn impl_py_method_def(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
2019-02-01 13:01:18 +00:00
|
|
|
spec: &FnSpec<'_>,
|
2018-07-03 20:28:40 +00:00
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2017-06-07 04:57:03 +00:00
|
|
|
if spec.args.is_empty() {
|
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Method({
|
2017-06-07 04:57:03 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDef {
|
2017-06-07 04:57:03 +00:00
|
|
|
ml_name: stringify!(#name),
|
2019-03-16 10:40:56 +00:00
|
|
|
ml_meth: pyo3::class::PyMethodType::PyNoArgsFunction(__wrap),
|
|
|
|
ml_flags: pyo3::ffi::METH_NOARGS,
|
2017-06-13 04:08:59 +00:00
|
|
|
ml_doc: #doc,
|
2017-06-07 04:57:03 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Method({
|
2017-06-07 04:57:03 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDef {
|
2017-06-07 04:57:03 +00:00
|
|
|
ml_name: stringify!(#name),
|
2019-03-16 10:40:56 +00:00
|
|
|
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
|
|
|
|
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
|
2017-06-13 04:08:59 +00:00
|
|
|
ml_doc: #doc,
|
2017-06-07 04:57:03 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub fn impl_py_method_def_new(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2017-05-20 06:14:59 +00:00
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::New({
|
2017-05-20 06:14:59 +00:00
|
|
|
#wrapper
|
2017-05-18 07:05:49 +00:00
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDef {
|
2017-05-20 06:14:59 +00:00
|
|
|
ml_name: stringify!(#name),
|
2019-03-16 10:40:56 +00:00
|
|
|
ml_meth: pyo3::class::PyMethodType::PyNewFunc(__wrap),
|
|
|
|
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
|
2017-06-13 04:08:59 +00:00
|
|
|
ml_doc: #doc,
|
2017-05-20 06:14:59 +00:00
|
|
|
}
|
|
|
|
})
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub fn impl_py_method_def_init(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2017-07-27 23:14:54 +00:00
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Init({
|
2017-07-27 23:14:54 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDef {
|
2017-07-27 23:14:54 +00:00
|
|
|
ml_name: stringify!(#name),
|
2019-03-16 10:40:56 +00:00
|
|
|
ml_meth: pyo3::class::PyMethodType::PyInitFunc(__wrap),
|
|
|
|
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
|
2017-07-27 23:14:54 +00:00
|
|
|
ml_doc: #doc,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub fn impl_py_method_def_class(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2017-06-08 18:29:40 +00:00
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Class({
|
2017-06-08 18:29:40 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDef {
|
2017-06-08 18:29:40 +00:00
|
|
|
ml_name: stringify!(#name),
|
2019-03-16 10:40:56 +00:00
|
|
|
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
|
|
|
|
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS |
|
|
|
|
pyo3::ffi::METH_CLASS,
|
2017-06-13 04:08:59 +00:00
|
|
|
ml_doc: #doc,
|
2017-06-08 18:29:40 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub fn impl_py_method_def_static(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2017-06-08 18:29:40 +00:00
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Static({
|
2017-06-08 18:29:40 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDef {
|
2017-06-08 18:29:40 +00:00
|
|
|
ml_name: stringify!(#name),
|
2019-03-16 10:40:56 +00:00
|
|
|
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
|
|
|
|
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS | pyo3::ffi::METH_STATIC,
|
2017-06-13 04:08:59 +00:00
|
|
|
ml_doc: #doc,
|
2017-06-08 18:29:40 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub fn impl_py_method_def_call(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2017-05-16 18:58:18 +00:00
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Call({
|
2017-05-16 18:58:18 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDef {
|
2017-05-16 18:58:18 +00:00
|
|
|
ml_name: stringify!(#name),
|
2019-03-16 10:40:56 +00:00
|
|
|
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
|
|
|
|
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
|
2017-06-13 04:08:59 +00:00
|
|
|
ml_doc: #doc,
|
2017-05-16 18:58:18 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub(crate) fn impl_py_setter_def(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
|
|
|
setter: &Option<String>,
|
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
let n = if let Some(ref name) = setter {
|
2017-05-16 18:58:18 +00:00
|
|
|
name.to_string()
|
|
|
|
} else {
|
2018-06-15 20:41:16 +00:00
|
|
|
let n = name.to_string();
|
2017-05-16 18:58:18 +00:00
|
|
|
if n.starts_with("set_") {
|
|
|
|
n[4..].to_string()
|
|
|
|
} else {
|
|
|
|
n
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Setter({
|
2017-05-16 18:58:18 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PySetterDef {
|
2017-05-16 18:58:18 +00:00
|
|
|
name: #n,
|
2017-07-23 17:07:23 +00:00
|
|
|
meth: __wrap,
|
2017-06-13 04:08:59 +00:00
|
|
|
doc: #doc,
|
2017-05-16 18:58:18 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:40 +00:00
|
|
|
pub(crate) fn impl_py_getter_def(
|
|
|
|
name: &syn::Ident,
|
|
|
|
doc: syn::Lit,
|
|
|
|
getter: &Option<String>,
|
|
|
|
wrapper: &TokenStream,
|
|
|
|
) -> TokenStream {
|
2019-02-18 19:07:41 +00:00
|
|
|
let n = if let Some(ref name) = getter {
|
2017-05-16 18:58:18 +00:00
|
|
|
name.to_string()
|
|
|
|
} else {
|
2018-06-15 20:41:16 +00:00
|
|
|
let n = name.to_string();
|
2017-05-16 18:58:18 +00:00
|
|
|
if n.starts_with("get_") {
|
|
|
|
n[4..].to_string()
|
|
|
|
} else {
|
|
|
|
n
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
2017-05-16 18:58:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
quote! {
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyMethodDefType::Getter({
|
2017-05-16 18:58:18 +00:00
|
|
|
#wrapper
|
|
|
|
|
2019-03-16 10:40:56 +00:00
|
|
|
pyo3::class::PyGetterDef {
|
2017-05-16 18:58:18 +00:00
|
|
|
name: #n,
|
2017-07-23 17:07:23 +00:00
|
|
|
meth: __wrap,
|
2017-06-13 04:08:59 +00:00
|
|
|
doc: #doc,
|
2017-05-16 18:58:18 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|