-
Notifications
You must be signed in to change notification settings - Fork 770
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 Bound::as_any
and Bound::into_any
(and same for Py
)
#3785
Conversation
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. |
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.
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_any
Bound::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 |
@@ -1243,24 +1270,16 @@ impl<T> Py<T> { | |||
/// | |||
/// # Safety | |||
/// `ptr` must point to a Python object of type T. | |||
#[inline] |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
pub fn unbind(self) -> Py<T> { | ||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a bit weird. Maybe an intermediate binding or some parentheses could improve it?
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice idiom of using ManuallyDrop
for conciseness instead of safety, compared to using forget
!
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.
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
Bound
API downstream inpydantic-core
.