macros: fix the check for applying `METH_NOARGS`

to only consider the Python argument list.

Fixes #2750
This commit is contained in:
Georg Brandl 2022-11-20 08:48:47 +01:00
parent 3408cc4200
commit ea9da80ab1
3 changed files with 18 additions and 2 deletions

View File

@ -0,0 +1,2 @@
Also apply the `NOARGS` argument convention to methods that have a single
`py: Python` argument.

View File

@ -200,7 +200,7 @@ impl CallingConvention {
/// Different other slots (tp_call, tp_new) can have other requirements /// Different other slots (tp_call, tp_new) can have other requirements
/// and are set manually (see `parse_fn_type` below). /// and are set manually (see `parse_fn_type` below).
pub fn from_signature(signature: &FunctionSignature<'_>) -> Self { pub fn from_signature(signature: &FunctionSignature<'_>) -> Self {
if signature.arguments.is_empty() { if signature.python_signature.has_no_args() {
Self::Noargs Self::Noargs
} else if signature.python_signature.accepts_kwargs { } else if signature.python_signature.accepts_kwargs {
// for functions that accept **kwargs, always prefer varargs // for functions that accept **kwargs, always prefer varargs
@ -457,7 +457,12 @@ impl<'a> FnSpec<'a> {
Ok(match self.convention { Ok(match self.convention {
CallingConvention::Noargs => { CallingConvention::Noargs => {
let call = rust_call(vec![]); let call = if !self.signature.arguments.is_empty() {
// Only `py` arg can be here
rust_call(vec![quote!(#py)])
} else {
rust_call(vec![])
};
quote! { quote! {
unsafe fn #ident<'py>( unsafe fn #ident<'py>(
#py: _pyo3::Python<'py>, #py: _pyo3::Python<'py>,

View File

@ -211,6 +211,15 @@ pub struct PythonSignature {
pub accepts_kwargs: bool, pub accepts_kwargs: bool,
} }
impl PythonSignature {
pub fn has_no_args(&self) -> bool {
self.positional_parameters.is_empty()
&& self.keyword_only_parameters.is_empty()
&& !self.accepts_varargs
&& !self.accepts_kwargs
}
}
pub struct FunctionSignature<'a> { pub struct FunctionSignature<'a> {
pub arguments: Vec<FnArg<'a>>, pub arguments: Vec<FnArg<'a>>,
pub python_signature: PythonSignature, pub python_signature: PythonSignature,