-
Notifications
You must be signed in to change notification settings - Fork 770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Function argument error handling improvements #1055
Comments
I was looking into this and I think the biggest issue is that the extraction methods in the proc macros return if spec.is_args(&name) {
return quote! {
let #arg_name = <#ty as pyo3::FromPyObject>::extract(_args.as_ref())?;
};
} generates code using I'm not sure how to proceed from this point without touching error-handling in |
One way would be to use a custom |
Following a similar approach, it would be possible to change the value of the /// Convert `PyDowncastError` to Python `TypeError`.
impl<'a> std::convert::From<PyDowncastError<'a>> for PyErr {
fn from(err: PyDowncastError) -> PyErr {
let from = err.from
.repr()
.map(|s| s.to_string_lossy())
.unwrap_or_else(|_| err.from.get_type().name())
.into_owned();
let to = err.to.into_owned();
exceptions::PyTypeError::py_err((from, to))
}
} Then it'd be possible to do something like: <&str as FromPyObject>::extract(foo).map_err(|e| match &e.pvalue {
PyErrValue::ToObject(to_obj) => {
let v = to_obj.to_object(gil.python());
if let Ok(downcast_tuple) = PyTuple::try_from(v.as_ref(gil.python())) {
let from = downcast_tuple.get_item(0).extract::<&str>().unwrap();
let to = downcast_tuple.get_item(1).extract::<&str>().unwrap();
return exceptions::PyTypeError::py_err(format!(
"Failed to convert the parameter {} with value {} to {}",
"foo", from, to
));
}
e
}
_ => e,
}) resulting in the following: >>> SomePyo3Type().foo(1.2)
TypeError: Failed to convert the parameter foo with value 1.2 to PyString Where In a proper version, the |
My thoughts I didn't have time to add earlier: Adding the parameter name
I think you've identified the correct part of the code to change to add the argument names. I was thinking we might be able to do something along the lines of:
it's not perfect, though seems like a way to tack on the argument name without too much trouble. Disclaimer: the above snippet almost certainly won't compile as-is; I'm typing this out without trying any code! Using more accurate types:I'm wondering if we should change the error type for This would allow us to generate the type information like |
I'm interested in working on this. It's something I have wanted in pyo3 for a while, and now with Hacktoberfest I have the motivation to actually look into it! (BTW you should label some easy issues with a hacktoberfest label). I think the most logical place to add this is somewhere around pyo3/pyo3-derive-backend/src/pymethod.rs Line 481 in 37ce406
pyo3/pyo3-derive-backend/src/pymethod.rs Line 521 in 37ce406
pyo3/pyo3-derive-backend/src/pymethod.rs Line 529 in 37ce406
So I'm thinking it might actually be best to add some error transformation to inject the argument name right here: pyo3/pyo3-derive-backend/src/pymethod.rs Line 419 in 37ce406
As this appears to be the only place where impl_arg_param is called.
Other options would be to wrap the entire body of |
Awesome, many thanks for taking this up! (For those interested, discussion has continued on #1212.) |
…onversion-error Enhance error messages of conversion errors
Is this complete now? |
I think this issue should probably be closed for two follow ups I'd like to see:
|
This is a sketch of ideas for a follow-up of #1050 to enable
#[pyfunction]
(and#[pymethods]
etc.) to report better errors for function inputs.Imagine that the following
#[pyfunction]
:After #1050, the error message when calling this function with invalid arguments is already much improved from PyO3
0.11.1
:I think that this error message can yet be improved further. There's two ways in which I'd like to see this improve:
Mention the argument which failed to convert.
Naming the function argument which failed to convert will help users locate exactly which function input is incorrect.
Provide mypy-style type annotations for the target type, where possible.
It's great to see that
None
can't convert toPyTuple
, but as a Python user really what I need to see is that the expected type isTuple[int, str]
.Put together, this might mean that our
foo
function above would output error messages like the below:I'm not super attached to the exact wording of the above if someone else has a better idea / something easier to implement.
Later today I'm going to add some thoughts on how these two pieces could be implented if anyone in the community is interested in championing these improvements.
The text was updated successfully, but these errors were encountered: