-
Notifications
You must be signed in to change notification settings - Fork 763
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 PyCapsule API #1980
Add PyCapsule API #1980
Conversation
b28e175
to
88e8cd1
Compare
88e8cd1
to
e0219b4
Compare
cb00ed3
to
ed21e8c
Compare
Just wanted to say thank-you for working on this - it's a really nice feature to add to PyO3. I've been a bit busy recently, however trying to find a moment to review when I can... |
No worries; thank you! I'm still chipping away as I get some time here and there. I'm sure there are some glaring errors I've missed, so put it here anyway if someone wanted to take a peak. |
Thanks! Sorry for not getting to this sooner. Unfortunately casting away lifetimes and types like this is really, really unsafe. For example, this segfaults: fn main() {
let cap: Py<PyCapsule> = Python::with_gil(|py| {
let name = CString::new("foo").unwrap();
let cap = PyCapsule::new(py, (), &name, None).unwrap();
let stuff: Vec<u8> = vec![1, 2, 3, 4];
cap.set_context(py, &stuff).unwrap();
cap.into()
});
Python::with_gil(|py| {
let ctx: Option<&&Vec<u8>> = cap.as_ref(py).get_context(py).unwrap();
dbg!(ctx);
})
} Or, you can implement transmute: fn transmute<'p, T, U>(py: Python<'p>, t: T) -> &'p U {
let name = CString::new("foo").unwrap();
let cap = PyCapsule::new(py, (), &name, None).unwrap();
cap.set_context(py, &t).unwrap();
let ctx: Option<&U> = cap.get_context(py).unwrap();
ctx.unwrap()
}
fn main() {
Python::with_gil(|py| {
let foo = 32u8;
let boom: &Vec<u32> = transmute(py, &foo);
dbg!(boom);
});
} And you can also use A good way to fix some of this is to introduce some variance - i.e., make the type Maybe you can use |
I suspected I'd fouled that up a bit. Thanks for the thorough explanation, the failing example is nice to have. I'll work on it; suspect this PR will be "slow to update". Working on it as time presents itself. :-) |
My current understanding is capsules are used to store by value and not by reference (unless static reference). If I modify your example to pass by value, it works fine. Thus, if I update the signatures of pub fn new<'py, T: 'static>(
py: Python<'py>,
value: T,
name: &CStr,
destructor: Option<ffi::PyCapsule_Destructor>,
) -> PyResult<&'py Self>;
pub fn set_context<'py, T: 'static>(&self, py: Python<'py>, context: T) -> PyResult<()>; I'm still pretty confident the value of Edit: |
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, in addition to discussion above I finally had some time to give this a read today. I think there's a few things which need to be solved yet.
Because the first field of the https://doc.rust-lang.org/reference/type-layout.html#the-c-representation
It's not clear to me what the use case for this would be. Also, macros are hard for users to figure out how to use without lots of good documentation, so without a strong motivation I'm unconvinced it's worth the maintenance cost. |
Thanks for the continued progress on this, I think it's getting there and will be a nice feature to add to PyO3! |
Thank you for the thorough reviews here, a lot of new stuff here for me, so appreciate it. I know you're busy! 🙏 |
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 looking great to me! Just needs an Added
CHANGELOG entry and then a couple of final suggestions. Also it might be nice to squash the commits, though I can also do that on merge.
Thanks for implementing this.
👍 this is shaping up really well, just wanted to say thanks again for working on this. It's a tricky one with a few design gotchas which are taking a bit of effort to hash out, so the patience with repeated iterations is appreciated. I think with luck we're close now 🤞 |
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.
Only a few nits left :)
@birkenfeld as I think you're very much on top of this PR, do you want to approve, squash-and-merge it once you're happy? Thanks for comprehensive reviewing, and thanks @milesgranger for all the iterations put in! 35 commits 😮 |
It's been a pleasure, learned a lot, and really appreciate the repeated and helpful reviews! 🙏 |
@davidhewitt will do - should the module be renamed to @milesgranger I'll do this change if @davidhewitt agrees and then merge it, everything else LGTM! |
Ah yes good spot, it should probably even live in |
That's probably even better. Not sure why |
|
and make slight copyedits to the docstring.
Thanks again @milesgranger! |
Will close #1193
Ref: https://docs.python.org/3/c-api/capsule.html#capsules
TODO: