-
Notifications
You must be signed in to change notification settings - Fork 784
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
move ffi module to separate crate #2126
Conversation
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! From glancing through this I have a few questions and comments.
Some tests and the datetime componenent of the ffi bindings had to remain in pyo3 itself due to integration with GILCell. Is this the desired solution?
Perhaps we can have some sort of "raw api" in pyo3-ffi, with pyo3 offering a safe wrapper?
I also noticed its readme: https://github.com/DSPOM2/pyo3/blob/main/pyo3-ffi/README.md
I know you just moved it, but this is pretty outdated and the link is broken. Would you be able to fix it? :)
Is that for a clean or incremental build? |
This is for a clean build. I wouldn't expect huge changes for an incremental build (after all pyo3 is not rebuild in that case) |
I will adress that along with your other comments :) |
Understood! And is that 3 seconds difference just between pyo3 and pyo3-ffi, or is that the whole compile including dependencies like |
The times I reported above were just how long I had to wait for cargo build to finish so it included the dependencies (after a cargo clean command). Both tests were performed after a clean build with the following command:
Compiled with pyo3
Compiled with pyo3-ffi
|
Thanks! I'm reasonably convinced that if we can make the split tidy this will be helpful for projects like yours 👍 |
1cdea7d
to
23d2acc
Compare
I created such a raw API. Instead of a GILCell this API uses a mutable static (like the original c macros in cpython). For backwards compatibility I then shadow this static with a wrapper that ensure that the datetime api is imported before use. Furthermore I reexport all functions/c macros that depends on this static in the ffi module. These shadowed implementations ensure that the API is imported (like the previous implementations did automatically with deref) and then call the raw C API. This should retain backwards compatibility while still exposing all raw functionality in pyo3-ffi. The implementation should compile down to basically the same thing as previously but its still very unsafe and it would be good if someone more familiar with the codebase checked this thoroughly. |
While writing the example for the documentation I noticed that the definition of |
96b4ef9
to
777eee9
Compare
I have moved most of the buildscript to pyo3-ffi as that is where all the linking takes places (this is what was causing the build failures on windows I believe). This is now ready for review |
In light of rust-lang/rust#53639, |
While I am pretty sure this implementation is safe (as there are essentially only ever reads and writes and no references are ever created) providing a cell would potentially be better API for downstream crates. I will take a look at this tomorrow (its quite late in my timezone) |
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! Got a few thoughts...
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, this is shaping up nicely.
Some additional comments added. Also, some housekeeping:
- The user-facing changes will need a CHANGELOG entry please.
- It would be great to update
Architecture.md
andContributing.md
where relevant. - The
coverage
CI inxtask/src/main.rs
will need to be updated to include this new package in coverage numbers.
pyo3-ffi/src/lib.rs
Outdated
/// Thread safety is ensured by the python GIL. | ||
/// Therefore accessing the contents of this cell in any form while the GIL is not held is UB | ||
#[repr(transparent)] | ||
pub struct UnsafeGILCell<T>(Cell<*mut T>); |
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.
Two thoughts:
Cell
just is a wrapper aroundUnsafeCell
, so I'd prefer we useUnsafeCell
as the inner type.- I don't think that we need a generic type here, given it's only used once in the datetime bindings. Also, we don't really need to give downstream users the possibility to write to the datetime pointer. Let me suggest something directly in the
datetime
bindings...
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.
My Intention with the pub cell was to let downstream crates (of pyo3_ffi) use the same cell. While this is trivial to implement it would be a nice QOL addition because having mutable statics for exactly the same purpose as here (loading some python type/api capsule) is a pretty common pattern if one uses raw ffi. However I your solution below is much nicer and in the end my UnsafeGILCell is probably not gonna cover all needs of downstream crates anyway and those crates should probably just use similar wrapper types instead. It feels a little out of place in an ffi wrapper anyway
Thanks for the feedback. I will implement your suggestions + housekeeping tomorrow. In regards to the Changelog: I noticted that the removal of the |
Don't worry about |
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, this looks a lot better :)
Writing these kinds of docs is not my strength so I would welcome some feedback 😄
I think they're pretty good, thanks! Don't let perfect be the enemy of good.
Thanks, I give it my best :) I haven't done this kind of contribution before so its just a bit of imposter syndrome. |
Sorry for the delay some unexpected things came up yesterday.
I found nothing relevant to update in |
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, this is looking great to me! @mejrs any further changes you want before this is merged?
I found nothing relevant to update in
Contributing.md
. Did you have anyhing specific in mind?
Nope that's fine, I was just listing off a few files which I thought would be worth checking in the light of a big structural change like this :)
I just have one tiny nit on the CHANGELOG...
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.
any further changes you want before this is merged?
LGTM :)
Thanks for doing all this work @DSPOM2
Perfect. I will apply the change to the changelog and then squash all the commits tomorrow. Then we are good to go :) |
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.
Looks very good! Mostly copy-edits, a few questions.
src/types/datetime.rs
Outdated
} | ||
} | ||
|
||
/// Type Check macros |
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 doesn't seem to be ta docstring for the macro?
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 added this doc comment to the macro because it seemed the best place to put it (it describes the function the macro generates) but I can make it a comment instead if you think that would be clearer
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.
Well, in the rendered docs it will show up as doc for the macro called ffi_fun_with_autoinit which seems to have nothing to do with type checking.
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.
Okay I will put it as a comment then so its lets confusing in the docs
Thanks for the thorough review :) |
commits are squashed and I think this is ready to merge now now 😄 |
The windows coverage job keeps failing but I doesn't sound related to this PR... Not too sure what going on there |
Agreed. Thanks again everyone for working on this! |
@DSPOM2 thanks for adding this. I have a proposal to add it to maturin in PyO3/maturin#804. |
This PR moves the ffi bindings to a seperate crate so they can be used independently from the rest of the crate.
The motivation here is that some special use cases might want to use the ffi bindings directly without touching the rest of pyo3.
Elimination of the dependency on the rest of pyo3 makes for much easier auditing and can improve compile times:
For my project this this reduces compile times for debug build from ~6 seconds to ~3 seconds. Note that the macros feature was not used in this comparison. I am using a fairly beefy CPU (8 core ryzen). On a laptop the improvements might be even larger.
Open Questions
There are some open questions on my side. I am not sure how to handle these as I am not as familiar with the pyo3 codebase