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

Deprecate Py::into_ref #3867

Merged
merged 2 commits into from
Feb 20, 2024
Merged

Conversation

LilyFoote
Copy link
Contributor

There's actually not much code that uses Py::into_ref left and almost all of it is easy to clean up.

@davidhewitt davidhewitt added the CI-skip-changelog Skip checking changelog entry label Feb 18, 2024
@@ -1036,6 +1036,7 @@ mod tests {
use std::error::Error;

Python::with_gil(|py| {
#[allow(deprecated)]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the only place I found that is tricky. The problem here is that Bound<'py, PyBaseException> doesn't implement std::error::Error.

I think the solution will be to update the impl_exception_boilerplate macro, but I suspect the naïve approach will run into the same orphan rules problem that I ran into with implementing std::convert::From in #3820 (comment). Though #3820 (comment) suggests we shouldn't implement std::error::Error here, so I'm not certain what the new way to say this is.

Copy link

codspeed-hq bot commented Feb 18, 2024

CodSpeed Performance Report

Merging #3867 will improve performances by 18.52%

Comparing LilyFoote:deprecate-py-into-ref (f8e5d21) with main (4ce9c35)

Summary

⚡ 2 improvements
✅ 77 untouched benchmarks

Benchmarks breakdown

Benchmark main LilyFoote:deprecate-py-into-ref Change
mapping_from_dict 355.6 ns 300 ns +18.52%
sequence_from_list 355.6 ns 300 ns +18.52%

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.

Thanks for this, great to see we've got to this point!

It's interesting to see the many .as_any() calls which need to be added, I think there's a papercut there which is probably a consequence of the way I prototyped Bound originally. Let's review that...

Otherwise, just a few small suggestions...

src/types/any.rs Outdated Show resolved Hide resolved
src/types/any.rs Outdated Show resolved Hide resolved
src/types/any.rs Outdated Show resolved Hide resolved
src/types/any.rs Outdated Show resolved Hide resolved
tests/test_proto_methods.rs Outdated Show resolved Hide resolved
@@ -82,6 +82,7 @@ fn test_getattr() {
let example_py = make_example(py);
assert_eq!(
example_py
.as_any()
Copy link
Member

Choose a reason for hiding this comment

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

These .as_any() calls are necessary, because the Deref implementation didn't work? Might be worth checking that, I wonder if we need to adjust.

Copy link
Contributor Author

@LilyFoote LilyFoote Feb 18, 2024

Choose a reason for hiding this comment

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

Yeah, we get errors like:

error[E0599]: no method named `getattr` found for struct `pyo3::Bound` in the current scope
  --> tests/test_proto_methods.rs:85:18
   |
83 | /             example_py
84 | |                 //.as_any()
85 | |                 .getattr("value")
   | |                 -^^^^^^^ method not found in `Bound<'_, ExampleClass>`
   | |_________________|
   | 

For more information about this error, try `rustc --explain E0599`.

I ran into needing loads of as_any() when looking at deprecating Py::as_ref too.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm. I think probably we need to adjust the bounds of the Deref implementation so that it works in this case, I've added that to the tracking issue. If you have an idea, feel free to open a PR. Otherwise, I'll sleep on it and see what ideas I have tomorrow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm wondering if we can solve this by implementing AsRef<PyAny> in the #[pyclass] proc macro. That would make the existing Deref bounds sufficient.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have noticed this too recently. I believe this happens only if T in Bound<T> is a #[pyclass] type. I don't think implementing AsRef<PyAny> is the right path here. I believe the current bound is wrong, because we're not using the AsRef functionality in any way. It just happens to work (mostly) because we're implementing that for the native types, but it feels like we're misusing it as a marker.

I believe an explicit AsRef might still be usefull, but it would need to be AsRef<Bound<PyAny>>, so I think the Deref bound could already be Bound<'py, T>: AsRef<Bound<'py, PyAny>>,.

Then we would need to find a way to correct the impl<'py, T> AsRef<Bound<'py, PyAny>> for Bound<'py, T> blanket implementation, because it uses the same hack. This can sadly not be implemented by the macro code because of orphan rules, so maybe using a marker trait together with a blanket implementation is a path that we can take.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think that's the right solution too. I haven't thought of a nice form for the marker trait, presumably it would need to be implemented for basically all T: PyTypeInfo except for PyAny.

Copy link
Member

@davidhewitt davidhewitt Feb 19, 2024

Choose a reason for hiding this comment

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

A possibly nice idea for the marker trait is something like HasPyBaseType (as PyAny doesn't have a base), but that might imply slightly more complex structure than what we really need here.

src/instance.rs Outdated Show resolved Hide resolved
@LilyFoote LilyFoote force-pushed the deprecate-py-into-ref branch 2 times, most recently from 3d2d50a to b97f769 Compare February 18, 2024 21:43
@davidhewitt davidhewitt added this pull request to the merge queue Feb 19, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Feb 20, 2024
@davidhewitt davidhewitt added this pull request to the merge queue Feb 20, 2024
Merged via the queue into PyO3:main with commit a939006 Feb 20, 2024
37 of 39 checks passed
@LilyFoote LilyFoote deleted the deprecate-py-into-ref branch February 20, 2024 09:50
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