Remove #[init] attribute

This commit is contained in:
kngwyu 2019-10-31 19:39:53 +09:00
parent 72debedc39
commit 8550e0f575
4 changed files with 10 additions and 84 deletions

View File

@ -24,7 +24,6 @@ pub enum FnType {
Setter(Option<String>),
Fn,
FnNew,
FnInit,
FnCall,
FnClass,
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__") {
res = Some(FnType::FnNew)
} 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__") {
res = Some(FnType::FnCall)
} 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") {
res = Some(FnType::FnNew)
} 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") {
res = Some(FnType::FnCall)
} else if path.is_ident("setter") || path.is_ident("getter") {

View File

@ -24,7 +24,6 @@ pub fn gen_py_method(
&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::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 => {
@ -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)
pub fn impl_wrap_class(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
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(
name: &syn::Ident,
doc: syn::Lit,

View File

@ -10,8 +10,6 @@ use std::ffi::CString;
pub enum PyMethodDefType {
/// Represents class `__new__` method
New(PyMethodDef),
/// Represents class `__init__` method
Init(PyMethodDef),
/// Represents class `__call__` method
Call(PyMethodDef),
/// Represents class method

View File

@ -372,23 +372,14 @@ where
type_object.tp_as_buffer = to_ptr(<T as class::buffer::PyBufferProtocolImpl>::tp_as_buffer());
// 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() {
methods.push(ffi::PyMethodDef_INIT);
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
type_object.tp_new = new;
// __init__ method
type_object.tp_init = init;
// __call__ method
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>() -> (
Option<ffi::newfunc>,
Option<ffi::initproc>,
Option<ffi::PyCFunctionWithKeywords>,
Vec<ffi::PyMethodDef>,
) {
let mut defs = Vec::new();
let mut call = None;
let mut new = None;
let mut init = None;
for def in T::py_methods() {
match *def {
@ -463,13 +452,6 @@ fn py_class_method_defs<T: PyMethodsProtocol>() -> (
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::Class(ref def)
| PyMethodDefType::Static(ref def) => {
@ -497,7 +479,7 @@ fn py_class_method_defs<T: PyMethodsProtocol>() -> (
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>) {