-
Notifications
You must be signed in to change notification settings - Fork 760
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
Add type info to conversion errors. #1050
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 thank you so much for kicking this effort off! I'm very pleased to see this - it's been on my mind for some time and agree it's a critical UX improvement we can make to PyO3!
I have added a few pieces of feedback below.
Also, if you really want to supercharge this, I have two further things I'd love to see:
- there's a second trait
FromPyObject
which has implementations for types likeOption<T>
. It would be really cool if extraction for thatOption<T>
mentionedOptional[int]
etc as the target type. - It would be 👌 if you added
impl std::error::Error
forPyDowncastError
to this PR!
Thanks for the review! I'll amend the PR, probably some time tomorrow! |
👍 I'll try to remember to merge #1051 in the morning so that you can use that to simplify the |
I spent some time trying to implement this, but I don't think it's easily doable: impl<'a, T> FromPyObject<'a> for Option<T>
where
T: FromPyObject<'a>,
{
fn extract(obj: &'a PyAny) -> PyResult<Self> {
if obj.as_ptr() == unsafe { ffi::Py_None() } {
Ok(None)
} else {
match T::extract(obj) {
Ok(v) => Ok(Some(v)),
Err(e) => Err(e),
}
}
}
} assumes that Unless I'm missing something, In other words, I don't think we can get the nice edit: Anyways, I might open a PR tomorrow to simplify the match, |
6bda2f9
to
e8596dd
Compare
Ah right, thanks for exploring the I've merged #1051 so you should be unblocked here now! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, but I don't think the lifetime 'b
matters.
e8596dd
to
0817b54
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this is now looking excellent to me! I have one final suggestion to handle the case when repr()
fails.
If I can make one further ask, could you please add a CHANGELOG entry? I suggest:
- Add additional context to `PyDowncastError`. [#1050](https://github.com/PyO3/pyo3/pull/1050)
src/err.rs
Outdated
write!( | ||
f, | ||
"Can't convert {} to {}", | ||
self.from.repr().map_err(|_| std::fmt::Error)?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in the error case we can fall back to showing the type as you did before:
self.from.repr().map_err(|_| std::fmt::Error)?, | |
self.from.repr().unwrap_or_else(|_| format!("object of type `{}`", self.from.get_type().name())), |
0817b54
to
63d6d4c
Compare
I had already amended the previous commit with:
I pushed out the version with the fallback to the |
Ah brilliant, thanks very much, I missed that. Once CI passes let's get this merged! 🚀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, actually one last little thing: looks like there's still some 'b
lifetimes unused which we can remove...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and applied that change. Sorry if that breaks it! 😄
CI is happy so let's merge it! Many thanks again |
@@ -56,7 +57,20 @@ pub struct PyErr { | |||
pub type PyResult<T> = Result<T, PyErr>; | |||
|
|||
/// Marker type that indicates an error while downcasting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
technically we should stop calling it a marker type now.
This is a draft to address #652. Initially, I tried to come up with a solution that keeps the downcast error 0-sized by parameterizing
PyDowncastError<T1, T2> where T1: PyTypeInfo, T2: PyTypeInfo
but I think there are cases where the underlying type is not easily accessible.I haven't worked much with pyo3 recently, so any pointers if I missed some obvious solution are much appreciated!
Thank you for contributing to pyo3!
Here are some things you should check for submitting your pull request:
cargo fmt
(This is checked by travis ci)cargo clippy
and check there are no hard errors (There are a bunch of existing warnings; This is also checked by travis)black .
. You can install black withpip install black
)You might want to run
tox
(pip install tox
) locally to check compatibility with all supported python versions. If you're using linux or mac you might find the Makefile helpful for testing.