-
Notifications
You must be signed in to change notification settings - Fork 914
feat: raw pointer capsule instantiation method #5689
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
base: main
Are you sure you want to change the base?
Conversation
f7825c3 to
be6bd40
Compare
be6bd40 to
26e4220
Compare
| /// | ||
| /// # Safety | ||
| /// | ||
| /// - `pointer` must be non-null and valid for the intended use case. |
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 don't think you need to say that the pointer must be non-null, as this is checked internally by the function and will raise an error if the pointer NULL.
davidhewitt
left a comment
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.
Thanks for working on this, I think the proposed functionality makes sense. Some initial comments on the design below.
| /// ``` | ||
| pub unsafe fn new_pointer( | ||
| py: Python<'_>, | ||
| pointer: *mut c_void, |
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.
How about using NonNull<c_void> here to make it clear in the API contract that the pointer must be non-null? Can then avoid checking for this in the code below, and defer to the caller to decide how they construct the NonNull.
| // We need to keep the name alive if it was provided, but since we're not | ||
| // using PyO3's destructor mechanism, we need to leak it or store it. | ||
| // For simplicity, we leak the name - this matches Python's expectation | ||
| // that capsule names are static or long-lived. | ||
| if let Some(name) = name { | ||
| std::mem::forget(name); | ||
| } |
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 suggest rather than leaking we make the name argument Option<&'static CStr>, given this is now trivial to construct.
I might even go further and recommend we always name capsules (this seems to be good practice), i.e. we could perhaps just have name: &'static CStr?
| py: Python<'_>, | ||
| pointer: *mut c_void, | ||
| name: Option<CString>, | ||
| destructor: Option<ffi::PyCapsule_Destructor>, |
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.
It might be helpful to users to document that the destructor must be a raw function unlike the new_with_destructor case because there is nowhere to store a destructor closure in this form.
| /// assert_eq!(ptr.as_ptr(), my_handler as *mut c_void); | ||
| /// }); | ||
| /// ``` | ||
| pub unsafe fn new_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.
Name bikeshedding, what do you think of new_with_pointer and new_with_pointer_and_destructor?
I somehow feel like new_pointer is describing that a "capsule pointer" gets returned rather than the capsule is constructed with a raw pointer.
Implements
PyCapsule::new_pointeras described in the issue abovePurpose
Allows users to write much simpler code, without getting under the hood of
pyo3-ffito make apyo3::PyCapsuleinstead of