From c70eba1aaa229d959627d7019e64da5bfb829f74 Mon Sep 17 00:00:00 2001 From: messense Date: Mon, 15 Mar 2021 14:22:11 +0800 Subject: [PATCH] Fix wrong class name in function call error message --- pyo3-macros-backend/src/pymethod.rs | 25 +++++++++++++++---------- src/derive_utils.rs | 24 +++++++++++++++++------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/pyo3-macros-backend/src/pymethod.rs b/pyo3-macros-backend/src/pymethod.rs index de6d06bb..271f2fe3 100644 --- a/pyo3-macros-backend/src/pymethod.rs +++ b/pyo3-macros-backend/src/pymethod.rs @@ -101,8 +101,7 @@ pub fn impl_wrap_cfunction_with_keywords( _args: *mut pyo3::ffi::PyObject, _kwargs: *mut pyo3::ffi::PyObject) -> *mut pyo3::ffi::PyObject { - const _LOCATION: &'static str = concat!( - stringify!(#cls), ".", stringify!(#python_name), "()"); + const _LOCATION: &'static str = concat!(stringify!(#python_name), "()"); pyo3::callback::handle_panic(|_py| { #slf let _args = _py.from_borrowed_ptr::(_args); @@ -126,8 +125,7 @@ pub fn impl_wrap_noargs(cls: &syn::Type, spec: &FnSpec<'_>, self_ty: &SelfType) _args: *mut pyo3::ffi::PyObject, ) -> *mut pyo3::ffi::PyObject { - const _LOCATION: &'static str = concat!( - stringify!(#cls), ".", stringify!(#python_name), "()"); + const _LOCATION: &'static str = concat!(stringify!(#python_name), "()"); pyo3::callback::handle_panic(|_py| { #slf #body @@ -153,7 +151,7 @@ pub fn impl_wrap_new(cls: &syn::Type, spec: &FnSpec<'_>) -> Result { use pyo3::callback::IntoPyCallbackOutput; - const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); + const _LOCATION: &'static str = concat!(stringify!(#python_name), "()"); pyo3::callback::handle_panic(|_py| { let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); @@ -182,7 +180,7 @@ pub fn impl_wrap_class(cls: &syn::Type, spec: &FnSpec<'_>) -> Result *mut pyo3::ffi::PyObject { - const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); + const _LOCATION: &'static str = concat!(stringify!(#python_name), "()"); pyo3::callback::handle_panic(|_py| { let _cls = pyo3::types::PyType::from_type_ptr(_py, _cls as *mut pyo3::ffi::PyTypeObject); let _args = _py.from_borrowed_ptr::(_args); @@ -210,7 +208,7 @@ pub fn impl_wrap_static(cls: &syn::Type, spec: &FnSpec<'_>) -> Result *mut pyo3::ffi::PyObject { - const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); + const _LOCATION: &'static str = concat!(stringify!(#python_name), "()"); pyo3::callback::handle_panic(|_py| { let _args = _py.from_borrowed_ptr::(_args); let _kwargs: Option<&pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); @@ -276,7 +274,7 @@ pub(crate) fn impl_wrap_getter( unsafe extern "C" fn __wrap( _slf: *mut pyo3::ffi::PyObject, _: *mut std::os::raw::c_void) -> *mut pyo3::ffi::PyObject { - const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); + const _LOCATION: &'static str = concat!(stringify!(#python_name), "()"); pyo3::callback::handle_panic(|_py| { #slf pyo3::callback::convert(_py, #getter_impl) @@ -328,7 +326,7 @@ pub(crate) fn impl_wrap_setter( _slf: *mut pyo3::ffi::PyObject, _value: *mut pyo3::ffi::PyObject, _: *mut std::os::raw::c_void) -> std::os::raw::c_int { - const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#python_name),"()"); + const _LOCATION: &'static str = concat!(stringify!(#python_name), "()"); pyo3::callback::handle_panic(|_py| { #slf let _value = _py.from_borrowed_ptr::(_value); @@ -408,11 +406,18 @@ pub fn impl_arg_params( } } + let cls_name = if let Some(cls) = self_ { + quote! { Some(<#cls as pyo3::type_object::PyTypeInfo>::NAME) } + } else { + quote! { None } + }; + // create array of arguments, and then parse Ok(quote! { { const DESCRIPTION: pyo3::derive_utils::FunctionDescription = pyo3::derive_utils::FunctionDescription { - fname: _LOCATION, + cls_name: #cls_name, + func_name: _LOCATION, positional_parameter_names: &[#(#positional_parameter_names),*], // TODO: https://github.com/PyO3/pyo3/issues/1439 - support specifying these positional_only_parameters: 0, diff --git a/src/derive_utils.rs b/src/derive_utils.rs index 1dec6fab..dbd69af9 100644 --- a/src/derive_utils.rs +++ b/src/derive_utils.rs @@ -22,7 +22,8 @@ pub struct KeywordOnlyParameterDescription { /// Function argument specification for a `#[pyfunction]` or `#[pymethod]`. #[derive(Debug)] pub struct FunctionDescription { - pub fname: &'static str, + pub cls_name: Option<&'static str>, + pub func_name: &'static str, pub positional_parameter_names: &'static [&'static str], pub positional_only_parameters: usize, pub required_positional_parameters: usize, @@ -32,6 +33,13 @@ pub struct FunctionDescription { } impl FunctionDescription { + fn full_name(&self) -> String { + if let Some(cls_name) = self.cls_name { + format!("{}.{}", cls_name, self.func_name) + } else { + self.func_name.to_string() + } + } /// Extracts the `args` and `kwargs` provided into `output`, according to this function /// definition. /// @@ -199,7 +207,7 @@ impl FunctionDescription { let msg = if self.required_positional_parameters != self.positional_parameter_names.len() { format!( "{} takes from {} to {} positional arguments but {} {} given", - self.fname, + self.full_name(), self.required_positional_parameters, self.positional_parameter_names.len(), args_provided, @@ -208,7 +216,7 @@ impl FunctionDescription { } else { format!( "{} takes {} positional arguments but {} {} given", - self.fname, + self.full_name(), self.positional_parameter_names.len(), args_provided, was @@ -220,21 +228,23 @@ impl FunctionDescription { fn multiple_values_for_argument(&self, argument: &str) -> PyErr { PyTypeError::new_err(format!( "{} got multiple values for argument '{}'", - self.fname, argument + self.full_name(), + argument )) } fn unexpected_keyword_argument(&self, argument: &PyAny) -> PyErr { PyTypeError::new_err(format!( "{} got an unexpected keyword argument '{}'", - self.fname, argument + self.full_name(), + argument )) } fn positional_only_keyword_arguments(&self, parameter_names: &[&str]) -> PyErr { let mut msg = format!( "{} got some positional-only arguments passed as keyword arguments: ", - self.fname + self.full_name() ); push_parameter_list(&mut msg, parameter_names); PyTypeError::new_err(msg) @@ -248,7 +258,7 @@ impl FunctionDescription { }; let mut msg = format!( "{} missing {} required {} {}: ", - self.fname, + self.full_name(), parameter_names.len(), argument_type, arguments,