Fix IntoPyCallbackOutput paper cuts#2326
Conversation
davidhewitt
left a comment
There was a problem hiding this comment.
Thanks!
First commit message - "Make arrays of pyclasses easier to sue" - oops :)
7e54611 to
7477842
Compare
davidhewitt
left a comment
There was a problem hiding this comment.
Really nice! Just a few final thoughts, and I think it would be better to change from IntoPyResult<R> -> IntoPyResult<T>. After that, I think this is good to merge 👍
| if false { | ||
| use _pyo3::impl_::ghost::IntoPyResult; | ||
| ret.into_py_result(); | ||
| } |
There was a problem hiding this comment.
I prefer this approach over what I did before. This won't actually call into_py_result if an user accidentally writes it for their type.
| /// If it does nothing, was it ever really there? 👻 | ||
| /// | ||
| /// This is code that is just type checked to e.g. create better compile errors, | ||
| /// but that never affects anything at runtime, | ||
| use crate::{IntoPy, PyErr, PyObject}; | ||
|
|
||
| #[allow(clippy::wrong_self_convention)] | ||
| pub trait IntoPyResult<T> { | ||
| fn into_py_result(&mut self) {} | ||
| } | ||
|
|
||
| impl<T> IntoPyResult<T> for T where T: IntoPy<PyObject> {} | ||
|
|
||
| impl<T, E> IntoPyResult<T> for Result<T, E> | ||
| where | ||
| T: IntoPy<PyObject>, | ||
| E: Into<PyErr>, | ||
| { | ||
| } |
There was a problem hiding this comment.
I prefer this approach of code that doesn't actually do anything 😉
| error[E0277]: the trait bound `Blah: IntoPyCallbackOutput<_>` is not satisfied | ||
| --> tests/ui/missing_intopy.rs:3:1 | ||
| | | ||
| 3 | #[pyo3::pyfunction] | ||
| | ^^^^^^^^^^^^^^^^^^^ the trait `IntoPyCallbackOutput<_>` is not implemented for `Blah` | ||
| | | ||
| note: required by a bound in `pyo3::callback::convert` | ||
| --> src/callback.rs | ||
| | | ||
| | T: IntoPyCallbackOutput<U>, | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `pyo3::callback::convert` | ||
| = note: this error originates in the attribute macro `pyo3::pyfunction` (in Nightly builds, run with -Z macro-backtrace for more info) |
There was a problem hiding this comment.
It's unfortunate this IntoPyCallbackOutput part is back - but overall I think it's worth it. The first part of the error is very very good.
src/impl_/ghost.rs
Outdated
| /// but that never affects anything at runtime, | ||
| use crate::{IntoPy, PyErr, PyObject}; | ||
|
|
||
| #[allow(clippy::wrong_self_convention)] |
There was a problem hiding this comment.
Is this lint actually necessary? I wonder if it's a hangover from experimentation.
There was a problem hiding this comment.
Yes, that hits the methods called into_* usually take self by value lint. The reason it takes &mut self is to prevent a cascade like this:
which is required by `Blah: IntoResult<Result<Blah, PyErr>>`
which is required by `Blah: IntoPyResult<Result<Blah, PyErr>>`
`&Blah: IntoPy<Py<PyAny>>`
which is required by `&Blah: IntoResult<Result<&Blah, PyErr>>`
which is required by `&Blah: IntoPyResult<Result<&Blah, PyErr>>`
`&mut Blah: IntoPy<Py<PyAny>>`
which is required by `&mut Blah: IntoResult<Result<&mut Blah, PyErr>>`
which is required by `&mut Blah: IntoPyResult<Result<&mut Blah, PyErr>>`There was a problem hiding this comment.
Ah I see! Do you think we should name the method differently then? E.g. into_py_result_hint or assert_into_py_result?
davidhewitt
left a comment
There was a problem hiding this comment.
Thanks, LGTM! To squash out the various interim commits I'm gonna squash-merge this one 👍
impl<T, const N: usize> IntoPy<PyObject> for [T; N]to useIntoPyfor it elements instead. Fixes IntoPyCallbackOutput<_> is not implimented for arrays of pyclass #2323IntoPyCallbackOutput, which (generally) generates a better compile error.For example, consider this:
Current error:
Error with this PR:
Todo: