2017-05-16 05:24:06 +00:00
|
|
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
|
|
|
|
|
|
|
use syn;
|
2018-06-15 20:41:16 +00:00
|
|
|
use quote::ToTokens;
|
2017-05-20 06:14:59 +00:00
|
|
|
use method::{FnArg, FnSpec, FnType};
|
2017-05-18 07:05:49 +00:00
|
|
|
|
2017-06-13 04:08:59 +00:00
|
|
|
use utils;
|
2018-06-15 20:41:16 +00:00
|
|
|
use proc_macro2::{TokenStream, Span};
|
2017-06-13 04:08:59 +00:00
|
|
|
|
2017-05-16 05:24:06 +00:00
|
|
|
|
2018-05-13 19:24:40 +00:00
|
|
|
pub fn gen_py_method<'a>(
|
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,
|
|
|
|
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);
|
2017-05-20 06:14:59 +00:00
|
|
|
let spec = FnSpec::parse(name, sig, meth_attrs);
|
2017-05-16 05:24:06 +00:00
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
match spec.tp {
|
2017-05-16 18:58:18 +00:00
|
|
|
FnType::Fn =>
|
2017-06-13 04:08:59 +00:00
|
|
|
impl_py_method_def(name, doc, &spec, &impl_wrap(cls, name, &spec, true)),
|
2017-05-20 06:14:59 +00:00
|
|
|
FnType::FnNew =>
|
2017-08-08 07:27:33 +00:00
|
|
|
impl_py_method_def_new(name, doc, &impl_wrap_new(cls, name, &spec)),
|
2017-07-27 23:14:54 +00:00
|
|
|
FnType::FnInit =>
|
|
|
|
impl_py_method_def_init(name, doc, &impl_wrap_init(cls, name, &spec)),
|
2017-05-20 06:14:59 +00:00
|
|
|
FnType::FnCall =>
|
2017-06-13 04:08:59 +00:00
|
|
|
impl_py_method_def_call(name, doc, &impl_wrap(cls, name, &spec, false)),
|
2017-06-08 18:29:40 +00:00
|
|
|
FnType::FnClass =>
|
2017-06-13 04:08:59 +00:00
|
|
|
impl_py_method_def_class(name, doc, &impl_wrap_class(cls, name, &spec)),
|
2017-06-08 18:29:40 +00:00
|
|
|
FnType::FnStatic =>
|
2017-06-13 04:08:59 +00:00
|
|
|
impl_py_method_def_static(name, doc, &impl_wrap_static(cls, name, &spec)),
|
2017-05-20 06:14:59 +00:00
|
|
|
FnType::Getter(ref getter) =>
|
2017-08-05 02:53:23 +00:00
|
|
|
impl_py_getter_def(name, doc, getter, &impl_wrap_getter(cls, name)),
|
2017-05-20 06:14:59 +00:00
|
|
|
FnType::Setter(ref setter) =>
|
2017-06-13 04:08:59 +00:00
|
|
|
impl_py_setter_def(name, doc, setter, &impl_wrap_setter(cls, name, &spec)),
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-16 05:24:06 +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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-06-15 20:41:16 +00:00
|
|
|
pub fn body_to_result(body: &TokenStream, spec: &FnSpec) -> TokenStream {
|
2018-04-06 15:19:32 +00:00
|
|
|
let output = &spec.output;
|
|
|
|
quote! {
|
|
|
|
use pyo3::ReturnTypeIntoPyResult;
|
|
|
|
let _result: PyResult<<#output as ReturnTypeIntoPyResult>::Inner> = {
|
|
|
|
#body
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
/// Generate function wrapper (PyCFunction, PyCFunctionWithKeywords)
|
2018-06-15 20:41:16 +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);
|
2017-05-20 06:14:59 +00:00
|
|
|
|
2017-06-07 04:57:03 +00:00
|
|
|
if spec.args.is_empty() && noargs {
|
2018-04-06 15:19:32 +00:00
|
|
|
let body_to_result = body_to_result(&body, spec);
|
|
|
|
|
2017-06-07 04:57:03 +00:00
|
|
|
quote! {
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2018-06-15 20:50:26 +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), "()");
|
2018-06-15 20:50:26 +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
|
|
|
|
2018-04-06 15:19:32 +00:00
|
|
|
#body_to_result
|
2018-06-15 20:50:26 +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);
|
|
|
|
let body_to_result = body_to_result(&body, spec);
|
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(
|
2018-06-15 20:50:26 +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
|
|
|
use pyo3::ToPyPointer;
|
|
|
|
const _LOCATION: &'static str = concat!(
|
2017-06-07 04:57:03 +00:00
|
|
|
stringify!(#cls), ".", stringify!(#name), "()");
|
2018-06-15 20:50:26 +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);
|
2018-06-15 20:50:26 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args);
|
|
|
|
let _kwargs = ::pyo3::argparse::get_kwargs(_py, _kwargs);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2018-04-06 15:19:32 +00:00
|
|
|
#body_to_result
|
2018-06-15 20:50:26 +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)
|
2018-06-15 20:41:16 +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(
|
2018-06-15 20:50:26 +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),"()");
|
2018-06-15 20:50:26 +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);
|
2018-06-15 20:50:26 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args);
|
|
|
|
let _kwargs = ::pyo3::argparse::get_kwargs(_py, _kwargs);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2017-07-23 17:07:23 +00:00
|
|
|
let _result = {
|
2017-07-20 21:21:57 +00:00
|
|
|
#body
|
|
|
|
};
|
2018-06-15 20:50:26 +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)
|
2018-06-15 20:41:16 +00:00
|
|
|
pub fn impl_wrap_new(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> TokenStream {
|
2017-07-23 17:07:23 +00:00
|
|
|
let names: Vec<syn::Ident> = spec.args.iter().enumerate().map(
|
2018-06-15 20:41:16 +00:00
|
|
|
|item| if item.1.py {syn::Ident::new("_py", Span::call_site())} else {
|
|
|
|
syn::Ident::new(&format!("arg{}", item.0), Span::call_site())}).collect();
|
2018-04-12 21:20:35 +00:00
|
|
|
let cb = quote! {
|
2018-05-05 13:50:04 +00:00
|
|
|
::pyo3::ReturnTypeIntoPyResult::return_type_into_py_result(#cls::#name(&_obj, #(#names),*))
|
2018-04-12 21:20:35 +00:00
|
|
|
};
|
2017-06-08 18:29:40 +00:00
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
let body = impl_arg_params(spec, cb);
|
2018-04-06 15:19:32 +00:00
|
|
|
let body_to_result = body_to_result(&body, spec);
|
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(
|
2018-06-15 20:50:26 +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
|
|
|
{
|
2017-08-08 07:58:12 +00:00
|
|
|
use std::ptr;
|
2017-08-08 07:27:33 +00:00
|
|
|
use pyo3::typeob::PyTypeInfo;
|
|
|
|
|
2017-07-20 21:21:57 +00:00
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2018-06-15 20:50:26 +00:00
|
|
|
let _pool = ::pyo3::GILPool::new();
|
|
|
|
let _py = ::pyo3::Python::assume_gil_acquired();
|
|
|
|
match ::pyo3::typeob::PyRawObject::new(_py, #cls::type_object(), _cls) {
|
2017-08-08 07:27:33 +00:00
|
|
|
Ok(_obj) => {
|
2018-06-15 20:50:26 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args);
|
|
|
|
let _kwargs = ::pyo3::argparse::get_kwargs(_py, _kwargs);
|
2017-08-08 07:27:33 +00:00
|
|
|
|
2018-04-06 15:19:32 +00:00
|
|
|
#body_to_result
|
2017-08-08 07:27:33 +00:00
|
|
|
|
|
|
|
match _result {
|
|
|
|
Ok(_) => _obj.into_ptr(),
|
|
|
|
Err(e) => {
|
2017-08-08 07:58:12 +00:00
|
|
|
e.restore(_py);
|
|
|
|
ptr::null_mut()
|
2017-08-08 07:27:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(e) => {
|
2017-08-08 07:58:12 +00:00
|
|
|
e.restore(_py);
|
|
|
|
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
|
2018-06-15 20:41:16 +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;
|
2018-06-15 20:41:16 +00:00
|
|
|
let result_empty: syn::Type = parse_quote!(PyResult<()>);
|
|
|
|
let empty: syn::Type = parse_quote!(());
|
|
|
|
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);
|
2018-04-06 15:19:32 +00:00
|
|
|
let body_to_result = body_to_result(&body, spec);
|
2017-07-27 23:14:54 +00:00
|
|
|
|
|
|
|
quote! {
|
|
|
|
#[allow(unused_mut)]
|
|
|
|
unsafe extern "C" fn __wrap(
|
2018-06-15 20:50:26 +00:00
|
|
|
_slf: *mut ::pyo3::ffi::PyObject,
|
|
|
|
_args: *mut ::pyo3::ffi::PyObject,
|
|
|
|
_kwargs: *mut ::pyo3::ffi::PyObject) -> ::pyo3::c_int
|
2017-07-27 23:14:54 +00:00
|
|
|
{
|
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
2018-06-15 20:50:26 +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);
|
2018-06-15 20:50:26 +00:00
|
|
|
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args);
|
|
|
|
let _kwargs = ::pyo3::argparse::get_kwargs(_py, _kwargs);
|
2017-07-27 23:14:54 +00:00
|
|
|
|
2018-04-06 15:19:32 +00:00
|
|
|
#body_to_result
|
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)
|
2018-06-15 20:41:16 +00:00
|
|
|
pub fn impl_wrap_class(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> TokenStream {
|
2017-07-23 17:07:23 +00:00
|
|
|
let names: Vec<syn::Ident> = spec.args.iter().enumerate().map(
|
2018-06-15 20:41:16 +00:00
|
|
|
|item| if item.1.py {syn::Ident::new("_py", Span::call_site())} else {
|
|
|
|
syn::Ident::new(&format!("arg{}", item.0), Span::call_site())}).collect();
|
2018-04-12 21:20:35 +00:00
|
|
|
let cb = quote! {
|
2018-05-05 13:50:04 +00:00
|
|
|
::pyo3::ReturnTypeIntoPyResult::return_type_into_py_result(#cls::#name(&_cls, #(#names),*))
|
2018-04-12 21:20:35 +00:00
|
|
|
};
|
2018-04-06 15:19:32 +00:00
|
|
|
|
2017-06-08 18:29:40 +00:00
|
|
|
let body = impl_arg_params(spec, cb);
|
2018-04-06 15:19:32 +00:00
|
|
|
let body_to_result = body_to_result(&body, spec);
|
2017-06-08 18:29:40 +00:00
|
|
|
|
|
|
|
quote! {
|
|
|
|
#[allow(unused_mut)]
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2018-06-15 20:50:26 +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),"()");
|
2018-06-15 20:50:26 +00:00
|
|
|
let _pool = ::pyo3::GILPool::new();
|
|
|
|
let _py = ::pyo3::Python::assume_gil_acquired();
|
|
|
|
let _cls = ::pyo3::PyType::from_type_ptr(_py, _cls as *mut ::pyo3::ffi::PyTypeObject);
|
|
|
|
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args);
|
|
|
|
let _kwargs = ::pyo3::argparse::get_kwargs(_py, _kwargs);
|
2017-07-20 21:21:57 +00:00
|
|
|
|
2018-04-06 15:19:32 +00:00
|
|
|
#body_to_result
|
2018-06-15 20:50:26 +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)
|
2018-06-15 20:41:16 +00:00
|
|
|
pub fn impl_wrap_static(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> TokenStream {
|
2017-07-23 17:07:23 +00:00
|
|
|
let names: Vec<syn::Ident> = spec.args.iter().enumerate().map(
|
2018-06-15 20:41:16 +00:00
|
|
|
|item| if item.1.py {syn::Ident::new("_py", Span::call_site())} else {
|
|
|
|
syn::Ident::new(&format!("arg{}", item.0), Span::call_site())}).collect();
|
2018-04-12 21:20:35 +00:00
|
|
|
let cb = quote! {
|
2018-05-05 13:50:04 +00:00
|
|
|
::pyo3::ReturnTypeIntoPyResult::return_type_into_py_result(#cls::#name(#(#names),*))
|
2018-04-12 21:20:35 +00:00
|
|
|
};
|
2017-06-08 18:29:40 +00:00
|
|
|
|
|
|
|
let body = impl_arg_params(spec, cb);
|
2018-04-06 15:19:32 +00:00
|
|
|
let body_to_result = body_to_result(&body, spec);
|
2017-06-08 18:29:40 +00:00
|
|
|
|
|
|
|
quote! {
|
|
|
|
#[allow(unused_mut)]
|
2017-07-23 17:07:23 +00:00
|
|
|
unsafe extern "C" fn __wrap(
|
2018-06-15 20:50:26 +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),"()");
|
2018-06-15 20:50:26 +00:00
|
|
|
let _pool = ::pyo3::GILPool::new();
|
|
|
|
let _py = ::pyo3::Python::assume_gil_acquired();
|
|
|
|
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args);
|
|
|
|
let _kwargs = ::pyo3::argparse::get_kwargs(_py, _kwargs);
|
2017-06-08 18:29:40 +00:00
|
|
|
|
2018-04-06 15:19:32 +00:00
|
|
|
#body_to_result
|
2018-06-15 20:50:26 +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(
|
2018-06-15 20:50:26 +00:00
|
|
|
_slf: *mut ::pyo3::ffi::PyObject, _: *mut ::pyo3::c_void) -> *mut ::pyo3::ffi::PyObject
|
2017-05-16 18:58:18 +00:00
|
|
|
{
|
2017-07-20 21:21:57 +00:00
|
|
|
use std;
|
|
|
|
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
|
|
|
|
2018-06-15 20:50:26 +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
|
|
|
|
2017-07-23 17:07:23 +00:00
|
|
|
match _slf.#name() {
|
2017-07-20 21:21:57 +00:00
|
|
|
Ok(val) => {
|
2017-07-23 17:07:23 +00:00
|
|
|
val.into_object(_py).into_ptr()
|
2017-07-20 21:21:57 +00:00
|
|
|
}
|
|
|
|
Err(e) => {
|
2017-07-23 17:07:23 +00:00
|
|
|
e.restore(_py);
|
2017-07-20 21:21:57 +00:00
|
|
|
std::ptr::null_mut()
|
|
|
|
}
|
|
|
|
}
|
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_setter(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> TokenStream {
|
2017-05-27 17:49:38 +00:00
|
|
|
if spec.args.len() < 1 {
|
|
|
|
println!("Not enough arguments for setter {}::{}", quote!{#cls}, name);
|
|
|
|
}
|
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(
|
2018-06-15 20:50:26 +00:00
|
|
|
_slf: *mut ::pyo3::ffi::PyObject,
|
|
|
|
_value: *mut ::pyo3::ffi::PyObject, _: *mut ::pyo3::c_void) -> ::pyo3::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),"()");
|
2018-06-15 20:50:26 +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
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
let _result = match <#val_ty as ::pyo3::FromPyObject>::extract(_value) {
|
2017-07-23 17:07:23 +00:00
|
|
|
Ok(_val) => _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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-06-15 20:41:16 +00:00
|
|
|
fn impl_call(_cls: &syn::Type, fname: &syn::Ident, spec: &FnSpec) -> TokenStream {
|
2017-07-23 17:07:23 +00:00
|
|
|
let names: Vec<syn::Ident> = spec.args.iter().enumerate().map(
|
|
|
|
|item| if item.1.py {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new("_py", Span::call_site())
|
2017-07-23 17:07:23 +00:00
|
|
|
} else {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new(&format!("arg{}", item.0), Span::call_site())
|
2017-07-23 17:07:23 +00:00
|
|
|
}
|
|
|
|
).collect();
|
2018-04-12 21:20:35 +00:00
|
|
|
quote! {
|
2018-05-05 13:50:04 +00:00
|
|
|
::pyo3::ReturnTypeIntoPyResult::return_type_into_py_result(_slf.#fname(#(#names),*))
|
2018-04-12 21:20:35 +00:00
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
|
2018-06-15 20:41:16 +00:00
|
|
|
pub fn impl_arg_params(spec: &FnSpec, body: TokenStream) -> TokenStream {
|
2017-06-22 19:32:01 +00:00
|
|
|
let args: Vec<FnArg> = spec.args.iter()
|
|
|
|
.filter(|item| !item.py).map(|item| item.clone()).collect();
|
|
|
|
if args.is_empty() {
|
2017-05-25 05:43:07 +00:00
|
|
|
return body
|
|
|
|
}
|
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() {
|
2017-06-22 19:32:01 +00:00
|
|
|
if arg.py {
|
|
|
|
continue
|
|
|
|
}
|
2017-05-20 06:14:59 +00:00
|
|
|
if ! (spec.is_args(&arg.name) || spec.is_kwargs(&arg.name)) {
|
2018-06-15 20:41:16 +00:00
|
|
|
let name = arg.name;
|
2017-06-14 05:37:26 +00:00
|
|
|
let kwonly = if spec.is_kw_only(&arg.name) {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new("true", Span::call_site())
|
2017-06-14 05:37:26 +00:00
|
|
|
} else {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new("false", Span::call_site())
|
2017-06-14 05:37:26 +00:00
|
|
|
};
|
|
|
|
|
2017-05-18 07:05:49 +00:00
|
|
|
let opt = if let Some(_) = arg.optional {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new("true", Span::call_site())
|
2017-06-14 05:37:26 +00:00
|
|
|
} else if let Some(_) = spec.default_value(&arg.name) {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new("true", Span::call_site())
|
2017-05-18 07:05:49 +00:00
|
|
|
} else {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new("false", Span::call_site())
|
2017-05-18 07:05:49 +00:00
|
|
|
};
|
2017-06-14 05:37:26 +00:00
|
|
|
|
2017-05-18 07:05:49 +00:00
|
|
|
params.push(
|
|
|
|
quote! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::argparse::ParamDescription{
|
2018-06-15 20:41:16 +00:00
|
|
|
name: stringify!(#name), is_optional: #opt, kw_only: #kwonly}
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
let placeholders: Vec<syn::Ident> = params.iter().map(
|
2018-06-15 20:41:16 +00:00
|
|
|
|_| syn::Ident::new("None", Span::call_site())
|
|
|
|
).collect();
|
2017-05-16 05:24:06 +00:00
|
|
|
|
|
|
|
// generate extrat args
|
2017-07-23 17:07:23 +00:00
|
|
|
let len = spec.args.len();
|
2017-05-20 06:14:59 +00:00
|
|
|
let mut rargs = spec.args.clone();
|
|
|
|
rargs.reverse();
|
2017-05-16 05:24:06 +00:00
|
|
|
let mut body = body;
|
2018-04-06 15:19:32 +00:00
|
|
|
|
2017-07-23 17:07:23 +00:00
|
|
|
for (idx, arg) in rargs.iter().enumerate() {
|
|
|
|
body = impl_arg_param(&arg, &spec, &body, len-idx-1);
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
|
|
|
|
2018-06-15 20:41:16 +00:00
|
|
|
let accept_args = syn::Ident::new(
|
|
|
|
if spec.accept_args() { "true" } else { "false" }, Span::call_site());
|
|
|
|
let accept_kwargs = syn::Ident::new(
|
|
|
|
if spec.accept_kwargs() { "true" } else { "false" }, Span::call_site());
|
2017-05-18 07:05:49 +00:00
|
|
|
|
2017-05-16 05:24:06 +00:00
|
|
|
// create array of arguments, and then parse
|
|
|
|
quote! {
|
2018-06-15 20:50:26 +00:00
|
|
|
const _PARAMS: &'static [::pyo3::argparse::ParamDescription<'static>] = &[
|
2017-05-16 05:24:06 +00:00
|
|
|
#(#params),*
|
|
|
|
];
|
|
|
|
|
2017-07-23 17:07:23 +00:00
|
|
|
let mut _output = [#(#placeholders),*];
|
2018-06-15 20:50:26 +00:00
|
|
|
match ::pyo3::argparse::parse_args(Some(_LOCATION), _PARAMS, &_args,
|
2017-07-23 17:07:23 +00:00
|
|
|
_kwargs, #accept_args, #accept_kwargs, &mut _output)
|
2017-06-07 02:26:59 +00:00
|
|
|
{
|
2017-05-16 05:24:06 +00:00
|
|
|
Ok(_) => {
|
2017-07-23 17:07:23 +00:00
|
|
|
let mut _iter = _output.iter();
|
2017-05-16 05:24:06 +00:00
|
|
|
|
|
|
|
#body
|
|
|
|
},
|
|
|
|
Err(err) => Err(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-15 20:41:16 +00:00
|
|
|
fn impl_arg_param(arg: &FnArg, spec: &FnSpec, body: &TokenStream, idx: usize) -> TokenStream {
|
2017-06-22 19:32:01 +00:00
|
|
|
if arg.py {
|
2018-04-06 15:19:32 +00:00
|
|
|
return body.clone();
|
2017-06-22 19:32:01 +00:00
|
|
|
}
|
2017-05-16 05:24:06 +00:00
|
|
|
let ty = arg.ty;
|
|
|
|
let name = arg.name;
|
2018-06-15 20:41:16 +00:00
|
|
|
let arg_name = syn::Ident::new(&format!("arg{}", idx), Span::call_site());
|
2017-05-16 05:24:06 +00:00
|
|
|
|
|
|
|
// First unwrap() asserts the iterated sequence is long enough (which should be guaranteed);
|
|
|
|
// second unwrap() asserts the parameter was not missing (which fn
|
|
|
|
// parse_args already checked for).
|
|
|
|
|
2017-05-20 06:14:59 +00:00
|
|
|
if spec.is_args(&name) {
|
2017-05-16 05:24:06 +00:00
|
|
|
quote! {
|
2018-05-14 20:44:30 +00:00
|
|
|
<#ty as ::pyo3::FromPyObject>::extract(_args.as_ref())
|
2018-04-12 21:20:35 +00:00
|
|
|
.and_then(|#arg_name| {
|
2018-05-14 20:44:30 +00:00
|
|
|
#body
|
|
|
|
})
|
2017-05-16 05:24:06 +00:00
|
|
|
}
|
2018-04-06 15:19:32 +00:00
|
|
|
} else if spec.is_kwargs(&name) {
|
2017-06-24 22:28:53 +00:00
|
|
|
quote! {{
|
2017-07-23 17:07:23 +00:00
|
|
|
let #arg_name = _kwargs;
|
2017-05-18 07:05:49 +00:00
|
|
|
#body
|
2017-06-24 22:28:53 +00:00
|
|
|
}}
|
2018-04-06 15:19:32 +00:00
|
|
|
} else {
|
2017-05-25 05:43:07 +00:00
|
|
|
if let Some(_) = arg.optional {
|
2017-05-18 07:05:49 +00:00
|
|
|
// default value
|
2018-06-15 20:41:16 +00:00
|
|
|
let mut default = TokenStream::new();
|
2017-05-20 06:14:59 +00:00
|
|
|
if let Some(d) = spec.default_value(name) {
|
2018-04-06 15:19:32 +00:00
|
|
|
let dt = quote! { Some(#d) };
|
2017-05-18 18:15:06 +00:00
|
|
|
dt.to_tokens(&mut default);
|
2017-05-18 07:05:49 +00:00
|
|
|
} else {
|
2018-06-15 20:41:16 +00:00
|
|
|
syn::Ident::new("None", Span::call_site()).to_tokens(&mut default);
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
2017-06-14 05:37:26 +00:00
|
|
|
|
2018-01-19 17:04:42 +00:00
|
|
|
quote! {
|
|
|
|
match
|
2017-05-25 05:43:07 +00:00
|
|
|
match _iter.next().unwrap().as_ref() {
|
2018-01-19 17:04:42 +00:00
|
|
|
Some(_obj) => {
|
|
|
|
if _obj.is_none() {
|
|
|
|
Ok(#default)
|
2017-05-25 05:43:07 +00:00
|
|
|
} else {
|
2018-01-19 17:04:42 +00:00
|
|
|
match _obj.extract() {
|
|
|
|
Ok(_obj) => Ok(Some(_obj)),
|
2017-05-25 05:43:07 +00:00
|
|
|
Err(e) => Err(e)
|
|
|
|
}
|
2017-05-19 04:35:08 +00:00
|
|
|
}
|
2017-05-25 05:43:07 +00:00
|
|
|
},
|
2018-05-14 20:44:30 +00:00
|
|
|
None => Ok(#default)
|
|
|
|
}
|
2018-01-19 17:04:42 +00:00
|
|
|
{
|
|
|
|
Ok(#arg_name) => #body,
|
|
|
|
Err(e) => Err(e)
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-20 06:14:59 +00:00
|
|
|
} else if let Some(default) = spec.default_value(name) {
|
2018-01-19 17:04:42 +00:00
|
|
|
quote! {
|
|
|
|
match match _iter.next().unwrap().as_ref() {
|
|
|
|
Some(_obj) => {
|
|
|
|
if _obj.is_none() {
|
|
|
|
Ok(#default)
|
|
|
|
} else {
|
|
|
|
match _obj.extract() {
|
|
|
|
Ok(_obj) => Ok(_obj),
|
|
|
|
Err(e) => Err(e),
|
2017-05-19 04:35:08 +00:00
|
|
|
}
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
2018-01-19 17:04:42 +00:00
|
|
|
},
|
|
|
|
None => Ok(#default)
|
|
|
|
} {
|
|
|
|
Ok(#arg_name) => #body,
|
|
|
|
Err(e) => Err(e)
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
2018-04-06 15:19:32 +00:00
|
|
|
} else {
|
2018-01-19 17:04:42 +00:00
|
|
|
quote! {
|
2018-05-14 20:44:30 +00:00
|
|
|
::pyo3::ObjectProtocol::extract(_iter.next().unwrap().unwrap())
|
2018-04-12 21:20:35 +00:00
|
|
|
.and_then(|#arg_name| {
|
2018-01-19 17:04:42 +00:00
|
|
|
#body
|
2018-04-12 21:20:35 +00:00
|
|
|
})
|
2017-05-18 07:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-15 20:41:16 +00:00
|
|
|
pub fn impl_py_method_def(name: &syn::Ident, doc: syn::Lit, spec: &FnSpec, wrapper: &TokenStream)
|
|
|
|
-> TokenStream
|
2017-06-13 04:08:59 +00:00
|
|
|
{
|
2017-06-07 04:57:03 +00:00
|
|
|
if spec.args.is_empty() {
|
|
|
|
quote! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Method({
|
2017-06-07 04:57:03 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDef {
|
2017-06-07 04:57:03 +00:00
|
|
|
ml_name: stringify!(#name),
|
2018-06-15 20:50:26 +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! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Method({
|
2017-06-07 04:57:03 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDef {
|
2017-06-07 04:57:03 +00:00
|
|
|
ml_name: stringify!(#name),
|
2018-06-15 20:50:26 +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-06-15 20:41:16 +00:00
|
|
|
pub fn impl_py_method_def_new(name: &syn::Ident, doc: syn::Lit, wrapper: &TokenStream) -> TokenStream
|
2017-06-13 04:08:59 +00:00
|
|
|
{
|
2017-05-20 06:14:59 +00:00
|
|
|
quote! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::New({
|
2017-05-20 06:14:59 +00:00
|
|
|
#wrapper
|
2017-05-18 07:05:49 +00:00
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDef {
|
2017-05-20 06:14:59 +00:00
|
|
|
ml_name: stringify!(#name),
|
2018-06-15 20:50:26 +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-06-15 20:41:16 +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! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Init({
|
2017-07-27 23:14:54 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDef {
|
2017-07-27 23:14:54 +00:00
|
|
|
ml_name: stringify!(#name),
|
2018-06-15 20:50:26 +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-06-15 20:41:16 +00:00
|
|
|
pub fn impl_py_method_def_class(name: &syn::Ident, doc: syn::Lit, wrapper: &TokenStream) -> TokenStream
|
2017-06-13 04:08:59 +00:00
|
|
|
{
|
2017-06-08 18:29:40 +00:00
|
|
|
quote! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Class({
|
2017-06-08 18:29:40 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDef {
|
2017-06-08 18:29:40 +00:00
|
|
|
ml_name: stringify!(#name),
|
2018-06-15 20:50:26 +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-06-15 20:41:16 +00:00
|
|
|
pub fn impl_py_method_def_static(name: &syn::Ident, doc: syn::Lit, wrapper: &TokenStream) -> TokenStream
|
2017-06-13 04:08:59 +00:00
|
|
|
{
|
2017-06-08 18:29:40 +00:00
|
|
|
quote! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Static({
|
2017-06-08 18:29:40 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDef {
|
2017-06-08 18:29:40 +00:00
|
|
|
ml_name: stringify!(#name),
|
2018-06-15 20:50:26 +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-06-15 20:41:16 +00:00
|
|
|
pub fn impl_py_method_def_call(name: &syn::Ident, doc: syn::Lit, wrapper: &TokenStream) -> TokenStream
|
2017-06-13 04:08:59 +00:00
|
|
|
{
|
2017-05-16 18:58:18 +00:00
|
|
|
quote! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Call({
|
2017-05-16 18:58:18 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDef {
|
2017-05-16 18:58:18 +00:00
|
|
|
ml_name: stringify!(#name),
|
2018-06-15 20:50:26 +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-06-15 20:41:16 +00:00
|
|
|
pub(crate) fn impl_py_setter_def(name: &syn::Ident, doc: syn::Lit, setter: &Option<String>, wrapper: &TokenStream)
|
|
|
|
-> TokenStream
|
2017-06-13 04:08:59 +00:00
|
|
|
{
|
2017-05-20 06:14:59 +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! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Setter({
|
2017-05-16 18:58:18 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +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-06-15 20:41:16 +00:00
|
|
|
pub(crate) fn impl_py_getter_def(name: &syn::Ident, doc: syn::Lit, getter: &Option<String>, wrapper: &TokenStream)
|
|
|
|
-> TokenStream
|
2017-06-13 04:08:59 +00:00
|
|
|
{
|
2017-05-20 06:14:59 +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! {
|
2018-06-15 20:50:26 +00:00
|
|
|
::pyo3::class::PyMethodDefType::Getter({
|
2017-05-16 18:58:18 +00:00
|
|
|
#wrapper
|
|
|
|
|
2018-06-15 20:50:26 +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
|
|
|
}
|