Skip to content
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

restrict IntoPyObject::Error to convert into PyErr #4489

Merged
merged 1 commit into from
Aug 25, 2024

Conversation

Icxolu
Copy link
Contributor

@Icxolu Icxolu commented Aug 24, 2024

This restricts the error type of IntoPyObject to be convertible into PyErr. While not strictly necessary this makes writing generic code much nicer, because we don't need to repeat a bound on the associated type all the time. It's also potentially less surprising to users because the error with an incompatible error will occur at implementation site instead of usage site. The usage without this bound are extremely limited, since the macros and nearly all the PyO3 API and containers require it, so it could only be called manually anyway.

XRef: #4480 (review)

@Icxolu Icxolu added the CI-skip-changelog Skip checking changelog entry label Aug 24, 2024
Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks great, thanks! A couple of brief thoughts, which might be better for follow ups...

src/conversions/hashbrown.rs Show resolved Hide resolved
{
type Target = PyTuple;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;

fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
Ok(array_into_tuple(py, [$(self.$n.into_pyobject(py)?.into_any().unbind()),+]).into_bound(py))
Ok(array_into_tuple(py, [$(self.$n.into_pyobject(py).map_err(Into::into)?.into_any().unbind()),+]).into_bound(py))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there's value in having a trait like

trait IntoPyObjectExt<'py>: IntoPyObject<'py> {
    fn try_into_pyobject(self, py: Python<'py>) -> PyResult<Self::Output>;
    fn try_into_pyobject_any(self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>>;
}

... which is sealed and has a single blanket impl for all T: IntoPyObject.

I don't know if I like those exact names, but the point is there's a lot of repeated patterns which I see us using (and I think users might experience the same).

We could make the trait crate-private in the short term while we figure out what feels good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting thought, we can definitely experiment with that. But this is really only effects generic code. Normal user code can usually just use the ?, because they get a concrete type and all PyAnyMethods are accessible via Deref

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, though I think we have a lot of generic code internally and I think users probably do write generic code from time to time, so it'd be nice to have a long term solution to make it easier.

Also I wonder if having such methods will help keep generic code bloat down by reusing common chunks, but that's just speculation until measured.

Either way, no need to block merge on this.

@davidhewitt davidhewitt added this pull request to the merge queue Aug 25, 2024
Merged via the queue into PyO3:main with commit b2a2a1d Aug 25, 2024
42 of 43 checks passed
@Icxolu Icxolu deleted the move-trait-bound branch August 25, 2024 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI-skip-changelog Skip checking changelog entry
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants