Allow slf: &PyClassShell<Self>
This commit is contained in:
parent
bdb66afe0a
commit
4d7dfafe2b
|
@ -27,7 +27,7 @@ pub enum FnType {
|
||||||
FnCall,
|
FnCall,
|
||||||
FnClass,
|
FnClass,
|
||||||
FnStatic,
|
FnStatic,
|
||||||
PySelf(syn::TypePath),
|
PySelfNew(syn::TypeReference),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
@ -103,13 +103,16 @@ impl<'a> FnSpec<'a> {
|
||||||
|
|
||||||
if fn_type == FnType::Fn && !has_self {
|
if fn_type == FnType::Fn && !has_self {
|
||||||
if arguments.is_empty() {
|
if arguments.is_empty() {
|
||||||
panic!("Static method needs #[staticmethod] attribute");
|
return Err(syn::Error::new_spanned(
|
||||||
|
name,
|
||||||
|
"Static method needs #[staticmethod] attribute",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let tp = match arguments.remove(0).ty {
|
let tp = match arguments.remove(0).ty {
|
||||||
syn::Type::Path(p) => replace_self(p),
|
syn::Type::Reference(r) => replace_self(r)?,
|
||||||
_ => panic!("Invalid type as self"),
|
x => return Err(syn::Error::new_spanned(x, "Invalid type as custom self")),
|
||||||
};
|
};
|
||||||
fn_type = FnType::PySelf(tp);
|
fn_type = FnType::PySelfNew(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FnSpec {
|
Ok(FnSpec {
|
||||||
|
@ -386,15 +389,19 @@ fn parse_attributes(attrs: &mut Vec<syn::Attribute>) -> syn::Result<(FnType, Vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace A<Self> with A<_>
|
// Replace &A<Self> with &A<_>
|
||||||
fn replace_self(path: &syn::TypePath) -> syn::TypePath {
|
fn replace_self(refn: &syn::TypeReference) -> syn::Result<syn::TypeReference> {
|
||||||
fn infer(span: proc_macro2::Span) -> syn::GenericArgument {
|
fn infer(span: proc_macro2::Span) -> syn::GenericArgument {
|
||||||
syn::GenericArgument::Type(syn::Type::Infer(syn::TypeInfer {
|
syn::GenericArgument::Type(syn::Type::Infer(syn::TypeInfer {
|
||||||
underscore_token: syn::token::Underscore { spans: [span] },
|
underscore_token: syn::token::Underscore { spans: [span] },
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
let mut res = path.to_owned();
|
let mut res = refn.to_owned();
|
||||||
for seg in &mut res.path.segments {
|
let tp = match &mut *res.elem {
|
||||||
|
syn::Type::Path(p) => p,
|
||||||
|
_ => return Err(syn::Error::new_spanned(refn, "unsupported argument")),
|
||||||
|
};
|
||||||
|
for seg in &mut tp.path.segments {
|
||||||
if let syn::PathArguments::AngleBracketed(ref mut g) = seg.arguments {
|
if let syn::PathArguments::AngleBracketed(ref mut g) = seg.arguments {
|
||||||
let mut args = syn::punctuated::Punctuated::new();
|
let mut args = syn::punctuated::Punctuated::new();
|
||||||
for arg in &g.args {
|
for arg in &g.args {
|
||||||
|
@ -415,5 +422,6 @@ fn replace_self(path: &syn::TypePath) -> syn::TypePath {
|
||||||
g.args = args;
|
g.args = args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res
|
res.lifetime = None;
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub fn gen_py_method(
|
||||||
};
|
};
|
||||||
|
|
||||||
let text_signature = match &spec.tp {
|
let text_signature = match &spec.tp {
|
||||||
FnType::Fn | FnType::PySelf(_) | FnType::FnClass | FnType::FnStatic => {
|
FnType::Fn | FnType::PySelfNew(_) | FnType::FnClass | FnType::FnStatic => {
|
||||||
utils::parse_text_signature_attrs(&mut *meth_attrs, name)?
|
utils::parse_text_signature_attrs(&mut *meth_attrs, name)?
|
||||||
}
|
}
|
||||||
FnType::FnNew => parse_erroneous_text_signature(
|
FnType::FnNew => parse_erroneous_text_signature(
|
||||||
|
@ -59,7 +59,7 @@ pub fn gen_py_method(
|
||||||
|
|
||||||
Ok(match spec.tp {
|
Ok(match spec.tp {
|
||||||
FnType::Fn => impl_py_method_def(name, doc, &spec, &impl_wrap(cls, name, &spec, true)),
|
FnType::Fn => impl_py_method_def(name, doc, &spec, &impl_wrap(cls, name, &spec, true)),
|
||||||
FnType::PySelf(ref self_ty) => impl_py_method_def(
|
FnType::PySelfNew(ref self_ty) => impl_py_method_def(
|
||||||
name,
|
name,
|
||||||
doc,
|
doc,
|
||||||
&spec,
|
&spec,
|
||||||
|
@ -127,7 +127,7 @@ pub fn impl_wrap_pyslf(
|
||||||
cls: &syn::Type,
|
cls: &syn::Type,
|
||||||
name: &syn::Ident,
|
name: &syn::Ident,
|
||||||
spec: &FnSpec<'_>,
|
spec: &FnSpec<'_>,
|
||||||
self_ty: &syn::TypePath,
|
self_ty: &syn::TypeReference,
|
||||||
noargs: bool,
|
noargs: bool,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let names = get_arg_names(spec);
|
let names = get_arg_names(spec);
|
||||||
|
@ -221,8 +221,7 @@ pub fn impl_proto_wrap(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) ->
|
||||||
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
|
/// Generate class method wrapper (PyCFunction, PyCFunctionWithKeywords)
|
||||||
pub fn impl_wrap_new(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> TokenStream {
|
pub fn impl_wrap_new(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);
|
||||||
let cb = quote! { #cls::#name(&_obj, #(#names),*) };
|
let cb = quote! { #cls::#name(#(#names),*) };
|
||||||
|
|
||||||
let body = impl_arg_params(spec, cb);
|
let body = impl_arg_params(spec, cb);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
|
@ -240,11 +239,11 @@ pub fn impl_wrap_new(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> T
|
||||||
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
let _args = _py.from_borrowed_ptr::<pyo3::types::PyTuple>(_args);
|
||||||
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
|
||||||
|
|
||||||
#body
|
# body
|
||||||
|
|
||||||
match <<#cls as pyo3::PyTypeInfo>::ConcreteLayout as pyo3::pyclass::PyClassNew>::new(_py, _result) {
|
match _result.and_then(|slf| pyo3::PyClassShell::new(_py, slf)) {
|
||||||
Ok(_slf) => _slf as _,
|
Ok(slf) => slf as _,
|
||||||
Err(e) => e.restore_and_null(),
|
Err(e) => e.restore_and_null(_py),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue