Skip to content

Commit 6a0221b

Browse files
authored
document FnType and refactor FnType::self_arg (#4276)
1 parent c67625d commit 6a0221b

File tree

1 file changed

+32
-26
lines changed

1 file changed

+32
-26
lines changed

pyo3-macros-backend/src/method.rs

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -192,16 +192,26 @@ fn handle_argument_error(pat: &syn::Pat) -> syn::Error {
192192
syn::Error::new(span, msg)
193193
}
194194

195+
/// Represents what kind of a function a pyfunction or pymethod is
195196
#[derive(Clone, Debug)]
196197
pub enum FnType {
198+
/// Represents a pymethod annotated with `#[getter]`
197199
Getter(SelfType),
200+
/// Represents a pymethod annotated with `#[setter]`
198201
Setter(SelfType),
202+
/// Represents a regular pymethod
199203
Fn(SelfType),
204+
/// Represents a pymethod annotated with `#[new]`, i.e. the `__new__` dunder.
200205
FnNew,
206+
/// Represents a pymethod annotated with both `#[new]` and `#[classmethod]` (in either order)
201207
FnNewClass(Span),
208+
/// Represents a pymethod annotated with `#[classmethod]`, like a `@classmethod`
202209
FnClass(Span),
210+
/// Represents a pyfunction or a pymethod annotated with `#[staticmethod]`, like a `@staticmethod`
203211
FnStatic,
212+
/// Represents a pyfunction annotated with `#[pyo3(pass_module)]
204213
FnModule(Span),
214+
/// Represents a pymethod or associated constant annotated with `#[classattr]`
205215
ClassAttribute,
206216
}
207217

@@ -224,7 +234,7 @@ impl FnType {
224234
error_mode: ExtractErrorMode,
225235
holders: &mut Holders,
226236
ctx: &Ctx,
227-
) -> TokenStream {
237+
) -> Option<TokenStream> {
228238
let Ctx { pyo3_path, .. } = ctx;
229239
match self {
230240
FnType::Getter(st) | FnType::Setter(st) | FnType::Fn(st) => {
@@ -235,35 +245,35 @@ impl FnType {
235245
ctx,
236246
);
237247
syn::Token![,](Span::call_site()).to_tokens(&mut receiver);
238-
receiver
239-
}
240-
FnType::FnNew | FnType::FnStatic | FnType::ClassAttribute => {
241-
quote!()
248+
Some(receiver)
242249
}
243250
FnType::FnClass(span) | FnType::FnNewClass(span) => {
244251
let py = syn::Ident::new("py", Span::call_site());
245252
let slf: Ident = syn::Ident::new("_slf_ref", Span::call_site());
246253
let pyo3_path = pyo3_path.to_tokens_spanned(*span);
247-
quote_spanned! { *span =>
254+
let ret = quote_spanned! { *span =>
248255
#[allow(clippy::useless_conversion)]
249256
::std::convert::Into::into(
250257
#pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(#py, &*(#slf as *const _ as *const *mut _))
251258
.downcast_unchecked::<#pyo3_path::types::PyType>()
252259
),
253-
}
260+
};
261+
Some(ret)
254262
}
255263
FnType::FnModule(span) => {
256264
let py = syn::Ident::new("py", Span::call_site());
257265
let slf: Ident = syn::Ident::new("_slf_ref", Span::call_site());
258266
let pyo3_path = pyo3_path.to_tokens_spanned(*span);
259-
quote_spanned! { *span =>
267+
let ret = quote_spanned! { *span =>
260268
#[allow(clippy::useless_conversion)]
261269
::std::convert::Into::into(
262270
#pyo3_path::impl_::pymethods::BoundRef::ref_from_ptr(#py, &*(#slf as *const _ as *const *mut _))
263271
.downcast_unchecked::<#pyo3_path::types::PyModule>()
264272
),
265-
}
273+
};
274+
Some(ret)
266275
}
276+
FnType::FnNew | FnType::FnStatic | FnType::ClassAttribute => None,
267277
}
268278
}
269279
}
@@ -658,10 +668,7 @@ impl<'a> FnSpec<'a> {
658668
}}
659669
}
660670
_ => {
661-
let self_arg = self_arg();
662-
if self_arg.is_empty() {
663-
quote! { function(#(#args),*) }
664-
} else {
671+
if let Some(self_arg) = self_arg() {
665672
let self_checker = holders.push_gil_refs_checker(self_arg.span());
666673
quote! {
667674
function(
@@ -670,6 +677,8 @@ impl<'a> FnSpec<'a> {
670677
#(#args),*
671678
)
672679
}
680+
} else {
681+
quote! { function(#(#args),*) }
673682
}
674683
}
675684
};
@@ -690,20 +699,17 @@ impl<'a> FnSpec<'a> {
690699
}};
691700
}
692701
call
693-
} else {
694-
let self_arg = self_arg();
695-
if self_arg.is_empty() {
696-
quote! { function(#(#args),*) }
697-
} else {
698-
let self_checker = holders.push_gil_refs_checker(self_arg.span());
699-
quote! {
700-
function(
701-
// NB #self_arg includes a comma, so none inserted here
702-
#pyo3_path::impl_::deprecations::inspect_type(#self_arg &#self_checker),
703-
#(#args),*
704-
)
705-
}
702+
} else if let Some(self_arg) = self_arg() {
703+
let self_checker = holders.push_gil_refs_checker(self_arg.span());
704+
quote! {
705+
function(
706+
// NB #self_arg includes a comma, so none inserted here
707+
#pyo3_path::impl_::deprecations::inspect_type(#self_arg &#self_checker),
708+
#(#args),*
709+
)
706710
}
711+
} else {
712+
quote! { function(#(#args),*) }
707713
};
708714

709715
// We must assign the output_span to the return value of the call,

0 commit comments

Comments
 (0)