Remove #[init] attribute
This commit is contained in:
parent
72debedc39
commit
8550e0f575
|
@ -24,7 +24,6 @@ pub enum FnType {
|
||||||
Setter(Option<String>),
|
Setter(Option<String>),
|
||||||
Fn,
|
Fn,
|
||||||
FnNew,
|
FnNew,
|
||||||
FnInit,
|
|
||||||
FnCall,
|
FnCall,
|
||||||
FnClass,
|
FnClass,
|
||||||
FnStatic,
|
FnStatic,
|
||||||
|
@ -291,7 +290,10 @@ fn parse_attributes(attrs: &mut Vec<syn::Attribute>) -> syn::Result<(FnType, Vec
|
||||||
if name.is_ident("new") || name.is_ident("__new__") {
|
if name.is_ident("new") || name.is_ident("__new__") {
|
||||||
res = Some(FnType::FnNew)
|
res = Some(FnType::FnNew)
|
||||||
} else if name.is_ident("init") || name.is_ident("__init__") {
|
} else if name.is_ident("init") || name.is_ident("__init__") {
|
||||||
res = Some(FnType::FnInit)
|
return Err(syn::Error::new_spanned(
|
||||||
|
name,
|
||||||
|
"#[init] is duplicated from PyO3 0.9.0!",
|
||||||
|
))
|
||||||
} else if name.is_ident("call") || name.is_ident("__call__") {
|
} else if name.is_ident("call") || name.is_ident("__call__") {
|
||||||
res = Some(FnType::FnCall)
|
res = Some(FnType::FnCall)
|
||||||
} else if name.is_ident("classmethod") {
|
} else if name.is_ident("classmethod") {
|
||||||
|
@ -322,7 +324,10 @@ fn parse_attributes(attrs: &mut Vec<syn::Attribute>) -> syn::Result<(FnType, Vec
|
||||||
if path.is_ident("new") {
|
if path.is_ident("new") {
|
||||||
res = Some(FnType::FnNew)
|
res = Some(FnType::FnNew)
|
||||||
} else if path.is_ident("init") {
|
} else if path.is_ident("init") {
|
||||||
res = Some(FnType::FnInit)
|
return Err(syn::Error::new_spanned(
|
||||||
|
path,
|
||||||
|
"#[init] is duplicated from PyO3 0.9.0!",
|
||||||
|
))
|
||||||
} else if path.is_ident("call") {
|
} else if path.is_ident("call") {
|
||||||
res = Some(FnType::FnCall)
|
res = Some(FnType::FnCall)
|
||||||
} else if path.is_ident("setter") || path.is_ident("getter") {
|
} else if path.is_ident("setter") || path.is_ident("getter") {
|
||||||
|
|
|
@ -24,7 +24,6 @@ pub fn gen_py_method(
|
||||||
&impl_wrap_pyslf(cls, name, &spec, self_ty, true),
|
&impl_wrap_pyslf(cls, name, &spec, self_ty, true),
|
||||||
),
|
),
|
||||||
FnType::FnNew => impl_py_method_def_new(name, doc, &impl_wrap_new(cls, name, &spec)),
|
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::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::FnClass => impl_py_method_def_class(name, doc, &impl_wrap_class(cls, name, &spec)),
|
||||||
FnType::FnStatic => {
|
FnType::FnStatic => {
|
||||||
|
@ -220,45 +219,6 @@ pub fn impl_wrap_new(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate function wrapper for ffi::initproc
|
|
||||||
fn impl_wrap_init(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
|
||||||
let cb = impl_call(cls, name, &spec);
|
|
||||||
let output = &spec.output;
|
|
||||||
let result_empty: syn::Type = syn::parse_quote!(PyResult<()>);
|
|
||||||
let empty: syn::Type = syn::parse_quote!(());
|
|
||||||
if output != &result_empty || output != &empty {
|
|
||||||
panic!("Constructor must return PyResult<()> or a ()");
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = impl_arg_params(&spec, cb);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
unsafe extern "C" fn __wrap(
|
|
||||||
_slf: *mut pyo3::ffi::PyObject,
|
|
||||||
_args: *mut pyo3::ffi::PyObject,
|
|
||||||
_kwargs: *mut pyo3::ffi::PyObject) -> pyo3::libc::c_int
|
|
||||||
{
|
|
||||||
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
|
|
||||||
let _py = pyo3::Python::assume_gil_acquired();
|
|
||||||
let _pool = pyo3::GILPool::new(_py);
|
|
||||||
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
|
|
||||||
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
|
||||||
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
|
||||||
|
|
||||||
#body
|
|
||||||
|
|
||||||
match _result {
|
|
||||||
Ok(_) => 0,
|
|
||||||
Err(e) => {
|
|
||||||
e.restore(_py);
|
|
||||||
-1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
|
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
|
||||||
pub fn impl_wrap_class(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
pub fn impl_wrap_class(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
||||||
let names: Vec<syn::Ident> = get_arg_names(&spec);
|
let names: Vec<syn::Ident> = get_arg_names(&spec);
|
||||||
|
@ -612,25 +572,6 @@ pub fn impl_py_method_def_new(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impl_py_method_def_init(
|
|
||||||
name: &syn::Ident,
|
|
||||||
doc: syn::Lit,
|
|
||||||
wrapper: &TokenStream,
|
|
||||||
) -> TokenStream {
|
|
||||||
quote! {
|
|
||||||
pyo3::class::PyMethodDefType::Init({
|
|
||||||
#wrapper
|
|
||||||
|
|
||||||
pyo3::class::PyMethodDef {
|
|
||||||
ml_name: stringify!(#name),
|
|
||||||
ml_meth: pyo3::class::PyMethodType::PyInitFunc(__wrap),
|
|
||||||
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS,
|
|
||||||
ml_doc: #doc,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn impl_py_method_def_class(
|
pub fn impl_py_method_def_class(
|
||||||
name: &syn::Ident,
|
name: &syn::Ident,
|
||||||
doc: syn::Lit,
|
doc: syn::Lit,
|
||||||
|
|
|
@ -10,8 +10,6 @@ use std::ffi::CString;
|
||||||
pub enum PyMethodDefType {
|
pub enum PyMethodDefType {
|
||||||
/// Represents class `__new__` method
|
/// Represents class `__new__` method
|
||||||
New(PyMethodDef),
|
New(PyMethodDef),
|
||||||
/// Represents class `__init__` method
|
|
||||||
Init(PyMethodDef),
|
|
||||||
/// Represents class `__call__` method
|
/// Represents class `__call__` method
|
||||||
Call(PyMethodDef),
|
Call(PyMethodDef),
|
||||||
/// Represents class method
|
/// Represents class method
|
||||||
|
|
|
@ -372,23 +372,14 @@ where
|
||||||
type_object.tp_as_buffer = to_ptr(<T as class::buffer::PyBufferProtocolImpl>::tp_as_buffer());
|
type_object.tp_as_buffer = to_ptr(<T as class::buffer::PyBufferProtocolImpl>::tp_as_buffer());
|
||||||
|
|
||||||
// normal methods
|
// normal methods
|
||||||
let (new, init, call, mut methods) = py_class_method_defs::<T>();
|
let (new, call, mut methods) = py_class_method_defs::<T>();
|
||||||
if !methods.is_empty() {
|
if !methods.is_empty() {
|
||||||
methods.push(ffi::PyMethodDef_INIT);
|
methods.push(ffi::PyMethodDef_INIT);
|
||||||
type_object.tp_methods = Box::into_raw(methods.into_boxed_slice()) as *mut _;
|
type_object.tp_methods = Box::into_raw(methods.into_boxed_slice()) as *mut _;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (None, Some(_)) = (new, init) {
|
|
||||||
panic!(
|
|
||||||
"{}.__new__ method is required if __init__ method defined",
|
|
||||||
T::NAME
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// __new__ method
|
// __new__ method
|
||||||
type_object.tp_new = new;
|
type_object.tp_new = new;
|
||||||
// __init__ method
|
|
||||||
type_object.tp_init = init;
|
|
||||||
// __call__ method
|
// __call__ method
|
||||||
type_object.tp_call = call;
|
type_object.tp_call = call;
|
||||||
|
|
||||||
|
@ -440,14 +431,12 @@ fn py_class_flags<T: PyTypeInfo>(type_object: &mut ffi::PyTypeObject) {
|
||||||
|
|
||||||
fn py_class_method_defs<T: PyMethodsProtocol>() -> (
|
fn py_class_method_defs<T: PyMethodsProtocol>() -> (
|
||||||
Option<ffi::newfunc>,
|
Option<ffi::newfunc>,
|
||||||
Option<ffi::initproc>,
|
|
||||||
Option<ffi::PyCFunctionWithKeywords>,
|
Option<ffi::PyCFunctionWithKeywords>,
|
||||||
Vec<ffi::PyMethodDef>,
|
Vec<ffi::PyMethodDef>,
|
||||||
) {
|
) {
|
||||||
let mut defs = Vec::new();
|
let mut defs = Vec::new();
|
||||||
let mut call = None;
|
let mut call = None;
|
||||||
let mut new = None;
|
let mut new = None;
|
||||||
let mut init = None;
|
|
||||||
|
|
||||||
for def in T::py_methods() {
|
for def in T::py_methods() {
|
||||||
match *def {
|
match *def {
|
||||||
|
@ -463,13 +452,6 @@ fn py_class_method_defs<T: PyMethodsProtocol>() -> (
|
||||||
panic!("Method type is not supoorted by tp_call slot")
|
panic!("Method type is not supoorted by tp_call slot")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PyMethodDefType::Init(ref def) => {
|
|
||||||
if let class::methods::PyMethodType::PyInitFunc(meth) = def.ml_meth {
|
|
||||||
init = Some(meth)
|
|
||||||
} else {
|
|
||||||
panic!("Method type is not supoorted by tp_init slot")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PyMethodDefType::Method(ref def)
|
PyMethodDefType::Method(ref def)
|
||||||
| PyMethodDefType::Class(ref def)
|
| PyMethodDefType::Class(ref def)
|
||||||
| PyMethodDefType::Static(ref def) => {
|
| PyMethodDefType::Static(ref def) => {
|
||||||
|
@ -497,7 +479,7 @@ fn py_class_method_defs<T: PyMethodsProtocol>() -> (
|
||||||
|
|
||||||
py_class_async_methods::<T>(&mut defs);
|
py_class_async_methods::<T>(&mut defs);
|
||||||
|
|
||||||
(new, init, call, defs)
|
(new, call, defs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn py_class_async_methods<T>(defs: &mut Vec<ffi::PyMethodDef>) {
|
fn py_class_async_methods<T>(defs: &mut Vec<ffi::PyMethodDef>) {
|
||||||
|
|
Loading…
Reference in New Issue