-
Notifications
You must be signed in to change notification settings - Fork 758
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
fixes #3325 -- mark AsPyPointer
as unsafe trait
#3358
Conversation
src/conversion.rs
Outdated
@@ -58,7 +58,9 @@ use std::ptr::NonNull; | |||
/// and the Python object is dropped immediately after the `0xabad1dea_u32.into_py(py).as_ptr()` | |||
/// expression is evaluated. To fix the problem, bind Python object to a local variable like earlier | |||
/// to keep the Python object alive until the end of its scope. | |||
pub trait AsPyPointer { | |||
/// | |||
/// Implementors must ensure this returns a valid pointer to a Python object. |
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.
Does this suffice? Do we want to demand some relation to the &self
parameter, e.g. that the resulting must be derived from and only from &self
to avoid implementations returning completely unrelated pointers?
As a more general observation. Do we need this in generic context? As an alternative would an inherent PyAny::as_ptr
combined with Deref<Target=PyAny>
not serve the same purpose without inventing a new contract via this trait?
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, this probably has a further requirement on the refcount (notably that this borrows a reference from self
, whereas into
shoudl be an owned reference). I'll update.
I'm not sure to what extent we could use the deref in place of this trait.
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.
I'm not sure to what extent we could use the deref in place of this trait.
My idea is to go from &self
to &PyAny
via Deref<Target=PyAny>
which is unambiguously safe due to the validity requirements of &PyAny
. From there we can go to *mut ffi::PyObject
via self.0.get()
without relying on extra contracts which must be upheld by implementors.
I think the main question is whether we use this in any situation where Deref<Target=PyAny>
does not apply. I would be surprised if we did tough, because returning a valid pointer to a Python object basically means I can construct a sufficiently short-lived &PyAny
from that pointer.
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.
I think PyAny::is
and also __traverse__
are the only public APIs which immediately come to my mind, but we can find nice solutions to those I'm sure.
I would definitely like to start by seeing how far adding the inherent methods to PyAny
and Py<T>
gets us, and see if there's much work after that to replace and deprecate the traits entirely.
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 makes sense to me. I'm not going to have time to work on it today. My suggestion would be: I think this makes sense to merge as is, and then looking to minimize and deprecate the usage of these traits is really orthagonal.
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.
See #3359 as a starting point.
My only reason to wait on merging this PR here is that if we can get to a point where the traits are deprecated in 0.20 then I'd prefer not to change them at all before that release.
At this point here are the functions that take
I think the first four can be straightly switched to something else (e.g. The conversion
|
Agreed re the conversion impls.
|
@@ -56,13 +56,15 @@ use std::ptr::NonNull; | |||
/// and the Python object is dropped immediately after the `0xabad1dea_u32.into_py(py).as_ptr()` | |||
/// expression is evaluated. To fix the problem, bind Python object to a local variable like earlier | |||
/// to keep the Python object alive until the end of its scope. | |||
pub trait AsPyPointer { | |||
/// | |||
/// Implementors must ensure this returns a valid pointer to a Python object, which borrows a reference count from `&self`. |
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 pointer may also be null, like in the case of the implementation of Option<T>
Realizing that I missed one on my original list: |
AsPyPointer
and IntoPyPointer
as unsafe trait
AsPyPointer
as unsafe trait
This handles the different between going for |
It handles going from |
Hmm I had a go in #3406 which looks a possible route. |
Given we're not sure about the decision in #3406, I'm beginning to warm to the idea to merging this now and releasing 0.20 with the remaining points addressed by the |
That works for me. |
Ok, let's do that. I'll create a follow up issue to finish the removal of this trait as we go. |
No description provided.