add Bound::as_any and Bound::into_any (and same for Py)#3785
add Bound::as_any and Bound::into_any (and same for Py)#3785davidhewitt merged 3 commits intoPyO3:mainfrom
Bound::as_any and Bound::into_any (and same for Py)#3785Conversation
CodSpeed Performance ReportMerging #3785 will degrade performances by 11.44%Comparing Summary
Benchmarks breakdown
|
|
I also think these are useful additions. I think I looked for these a few time while porting tests and examples to the new API. I not really a fan of |
|
Thanks, that's good to have support that these proposals make sense 👍 I think the main thing to consider before merge would be if there's better names than I think I can avoid the |
42db4af to
09224f5
Compare
|
I managed to find alternatives to the |
Cool, I like these implementations a lot more. They might be a little longer, but don't feel so "unsafe". As for the naming, I like them. I think they convey the intent well, and read nicely when written in code. |
adamreichold
left a comment
There was a problem hiding this comment.
If we are going out of our way to avoid transmute, I think we should audit at least the other conversions in this module to make their implementation styles consistent.
b08d2fe to
33c68be
Compare
Bound::as_any and Bound::into_anyBound::as_any and Bound::into_any (and same for Py)
|
That's a very good suggestion. I've pushed two more commits, which carry out the following:
No more |
| /// | ||
| /// # Safety | ||
| /// `ptr` must point to a Python object of type T. | ||
| #[inline] |
There was a problem hiding this comment.
Removed inline here because it's only used in this module, I figure it'll be inlined anyway.
There was a problem hiding this comment.
While it is available for inlining (just because it is in the same crate), #[inline] will still increase the likelyhood that it actually is inlined, i.e. it will bias the heuristics towards using that option, i.e. I would not remove it since this should be compiled away completed only after inlining which should happen immediately in the first pass of LLVM over the resulting MIR.
|
(The only code I didn't touch is changed already in #3776.) |
33c68be to
7cde30c
Compare
src/instance.rs
Outdated
| // Safety: the type T is known to be correct and the ownership of the | ||
| // pointer is transferred to the new Py<T> instance. | ||
| unsafe { Py::from_non_null(self.into_non_null()) } | ||
| unsafe { Py::from_non_null(ManuallyDrop::new(self).1 .0) } |
There was a problem hiding this comment.
This looks a bit weird. Maybe an intermediate binding or some parentheses could improve it?
There was a problem hiding this comment.
For now I'll go for
let non_null = (ManuallyDrop::new(self).1).0;
unsafe { Py::from_non_null(non_null) }| let ptr = self.0.as_ptr(); | ||
| std::mem::forget(self); | ||
| ptr | ||
| ManuallyDrop::new(self).0.as_ptr() |
There was a problem hiding this comment.
This is a nice idiom of using ManuallyDrop for conciseness instead of safety, compared to using forget!
There was a problem hiding this comment.
Yes, it only works when pulling a Copy field out of the ManuallyDrop, but fortunately that's what we're doing here! 😂
7cde30c to
49a57df
Compare
|
Thanks again both! 🚀 |
Split from #3606
This PR adds new methods
Bound::as_any()andBound::into_any()which can be used to castBound<T>intoBound<PyAny>.I found these useful when testing out the new
BoundAPI downstream inpydantic-core.