document FnType and refactor FnType::self_arg (#4276)
This commit is contained in:
parent
c67625d683
commit
6a0221ba2c
|
@ -192,16 +192,26 @@ fn handle_argument_error(pat: &syn::Pat) -> syn::Error {
|
||||||
syn::Error::new(span, msg)
|
syn::Error::new(span, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents what kind of a function a pyfunction or pymethod is
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum FnType {
|
pub enum FnType {
|
||||||
|
/// Represents a pymethod annotated with `#[getter]`
|
||||||
Getter(SelfType),
|
Getter(SelfType),
|
||||||
|
/// Represents a pymethod annotated with `#[setter]`
|
||||||
Setter(SelfType),
|
Setter(SelfType),
|
||||||
|
/// Represents a regular pymethod
|
||||||
Fn(SelfType),
|
Fn(SelfType),
|
||||||
|
/// Represents a pymethod annotated with `#[new]`, i.e. the `__new__` dunder.
|
||||||
FnNew,
|
FnNew,
|
||||||
|
/// Represents a pymethod annotated with both `#[new]` and `#[classmethod]` (in either order)
|
||||||
FnNewClass(Span),
|
FnNewClass(Span),
|
||||||
|
/// Represents a pymethod annotated with `#[classmethod]`, like a `@classmethod`
|
||||||
FnClass(Span),
|
FnClass(Span),
|
||||||
|
/// Represents a pyfunction or a pymethod annotated with `#[staticmethod]`, like a `@staticmethod`
|
||||||
FnStatic,
|
FnStatic,
|
||||||
|
/// Represents a pyfunction annotated with `#[pyo3(pass_module)]
|
||||||
FnModule(Span),
|
FnModule(Span),
|
||||||
|
/// Represents a pymethod or associated constant annotated with `#[classattr]`
|
||||||
ClassAttribute,
|
ClassAttribute,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +234,7 @@ impl FnType {
|
||||||
error_mode: ExtractErrorMode,
|
error_mode: ExtractErrorMode,
|
||||||
holders: &mut Holders,
|
holders: &mut Holders,
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
) -> TokenStream {
|
) -> Option<TokenStream> {
|
||||||
let Ctx { pyo3_path, .. } = ctx;
|
let Ctx { pyo3_path, .. } = ctx;
|
||||||
match self {
|
match self {
|
||||||
FnType::Getter(st) | FnType::Setter(st) | FnType::Fn(st) => {
|
FnType::Getter(st) | FnType::Setter(st) | FnType::Fn(st) => {
|
||||||
|
@ -235,35 +245,35 @@ impl FnType {
|
||||||
ctx,
|
ctx,
|
||||||
);
|
);
|
||||||
syn::Token![,](Span::call_site()).to_tokens(&mut receiver);
|
syn::Token![,](Span::call_site()).to_tokens(&mut receiver);
|
||||||
receiver
|
Some(receiver)
|
||||||
}
|
|
||||||
FnType::FnNew | FnType::FnStatic | FnType::ClassAttribute => {
|
|
||||||
quote!()
|
|
||||||
}
|
}
|
||||||
FnType::FnClass(span) | FnType::FnNewClass(span) => {
|
FnType::FnClass(span) | FnType::FnNewClass(span) => {
|
||||||
let py = syn::Ident::new("py", Span::call_site());
|
let py = syn::Ident::new("py", Span::call_site());
|
||||||
let slf: Ident = syn::Ident::new("_slf_ref", Span::call_site());
|
let slf: Ident = syn::Ident::new("_slf_ref", Span::call_site());
|
||||||
let pyo3_path = pyo3_path.to_tokens_spanned(*span);
|
let pyo3_path = pyo3_path.to_tokens_spanned(*span);
|
||||||
quote_spanned! { *span =>
|
let ret = quote_spanned! { *span =>
|
||||||
#[allow(clippy::useless_conversion)]
|
#[allow(clippy::useless_conversion)]
|
||||||
::std::convert::Into::into(
|
::std::convert::Into::into(
|
||||||
#pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(#py, &*(#slf as *const _ as *const *mut _))
|
#pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(#py, &*(#slf as *const _ as *const *mut _))
|
||||||
.downcast_unchecked::<#pyo3_path::types::PyType>()
|
.downcast_unchecked::<#pyo3_path::types::PyType>()
|
||||||
),
|
),
|
||||||
}
|
};
|
||||||
|
Some(ret)
|
||||||
}
|
}
|
||||||
FnType::FnModule(span) => {
|
FnType::FnModule(span) => {
|
||||||
let py = syn::Ident::new("py", Span::call_site());
|
let py = syn::Ident::new("py", Span::call_site());
|
||||||
let slf: Ident = syn::Ident::new("_slf_ref", Span::call_site());
|
let slf: Ident = syn::Ident::new("_slf_ref", Span::call_site());
|
||||||
let pyo3_path = pyo3_path.to_tokens_spanned(*span);
|
let pyo3_path = pyo3_path.to_tokens_spanned(*span);
|
||||||
quote_spanned! { *span =>
|
let ret = quote_spanned! { *span =>
|
||||||
#[allow(clippy::useless_conversion)]
|
#[allow(clippy::useless_conversion)]
|
||||||
::std::convert::Into::into(
|
::std::convert::Into::into(
|
||||||
#pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(#py, &*(#slf as *const _ as *const *mut _))
|
#pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(#py, &*(#slf as *const _ as *const *mut _))
|
||||||
.downcast_unchecked::<#pyo3_path::types::PyModule>()
|
.downcast_unchecked::<#pyo3_path::types::PyModule>()
|
||||||
),
|
),
|
||||||
}
|
};
|
||||||
|
Some(ret)
|
||||||
}
|
}
|
||||||
|
FnType::FnNew | FnType::FnStatic | FnType::ClassAttribute => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,10 +668,7 @@ impl<'a> FnSpec<'a> {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let self_arg = self_arg();
|
if let Some(self_arg) = self_arg() {
|
||||||
if self_arg.is_empty() {
|
|
||||||
quote! { function(#(#args),*) }
|
|
||||||
} else {
|
|
||||||
let self_checker = holders.push_gil_refs_checker(self_arg.span());
|
let self_checker = holders.push_gil_refs_checker(self_arg.span());
|
||||||
quote! {
|
quote! {
|
||||||
function(
|
function(
|
||||||
|
@ -670,6 +677,8 @@ impl<'a> FnSpec<'a> {
|
||||||
#(#args),*
|
#(#args),*
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
quote! { function(#(#args),*) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -690,20 +699,17 @@ impl<'a> FnSpec<'a> {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
call
|
call
|
||||||
} else {
|
} else if let Some(self_arg) = self_arg() {
|
||||||
let self_arg = self_arg();
|
let self_checker = holders.push_gil_refs_checker(self_arg.span());
|
||||||
if self_arg.is_empty() {
|
quote! {
|
||||||
quote! { function(#(#args),*) }
|
function(
|
||||||
} else {
|
// NB #self_arg includes a comma, so none inserted here
|
||||||
let self_checker = holders.push_gil_refs_checker(self_arg.span());
|
#pyo3_path::impl_::deprecations::inspect_type(#self_arg &#self_checker),
|
||||||
quote! {
|
#(#args),*
|
||||||
function(
|
)
|
||||||
// NB #self_arg includes a comma, so none inserted here
|
|
||||||
#pyo3_path::impl_::deprecations::inspect_type(#self_arg &#self_checker),
|
|
||||||
#(#args),*
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
quote! { function(#(#args),*) }
|
||||||
};
|
};
|
||||||
|
|
||||||
// We must assign the output_span to the return value of the call,
|
// We must assign the output_span to the return value of the call,
|
||||||
|
|
Loading…
Reference in New Issue