-
Notifications
You must be signed in to change notification settings - Fork 533
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 pyo3 integration #542
Add pyo3 integration #542
Conversation
2aacddf
to
7622931
Compare
Not sure how can we add |
You need a wrapper type by the looks of it |
4b95ee0
to
a45e1ce
Compare
src/offset/fixed.rs
Outdated
// TODO: not sure how to convert this to timezone struct to | ||
// compare since we don't really have a struct to downcast | ||
assert_eq!(offset.as_ref(py), py_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.
@davidhewitt Do you know if there is any way that we are able to compare timezone? I tried comparing with Eq
but even though both have the same value it didn't seemed to pass.
Sorry for the long wait, I was waiting for 2018 edition move but it didn't seemed to happen (and probably not anytime soon). Currently I a couple of types that involves timezone ( Not sure where would be best to document these missing stuff. |
Rebased to latest master with 2018 edition and got it compiling, need to double check where I left off. |
What's the use case for this? Why would it be helpful/good for this to live inside chrono instead of in a separate crate? I like PyO3 and have worked with it before, but it will take a while before I'm comfortable adding a bunch of extra stuff to chrono given the lack of maintenance this crate has been seeing for a while. |
So next time when users use pyo3, chrono integration would be seamless, adding it in this crate allows using the internal representation of chrono and allows to convert directly to python. An alternative would be to add it to pyo3 but that have the same limitation as adding it as a separate crate, at least the integration is just like serde where you can just add a feature and use it rather than having to look up a separate crate, the pyo3 stuff is pretty much separated so it does not add that much of maintenance. Adding it to a separate crate would require adding newtypes to implement the pyo3 traits due to orphan rules and may be quite inflexible in case users need the original types from chrono. |
Okay, that does make some sense. In terms of how we implement this, I think I'd prefer to have a single top-level |
I moved most parts into Also figured out how to convert from python utc. I guess two more things left is to figure out conversion from python fixedoffset, I guess that we can just subtract the time from python to ours, I have some rough idea on this now. After that the last thing is datetime. I guess I will convert it to draft for those two items but it should be good for review for most parts now. |
72f5cb2
to
db732b5
Compare
Weird, not sure why stuff used to passed and now starts failing due to associated functions visibility. |
Sorry for the long delay, finally took a quick look at this. Regarding segfaults, looks like you've got incorrect ownership. The below: unsafe {
PyDateTime_IMPORT();
PyObject::from_owned_ptr(py, PyDateTime_TimeZone_UTC())
} should be unsafe {
PyDateTime_IMPORT();
PyObject::from_borrowed_ptr(py, PyDateTime_TimeZone_UTC())
} Because @djc - I wonder if you have an opinion where this integration should live? Given that |
(I resurrected PyO3/pyo3#1588 which I'll probably merge shortly for PyO3 0.17, which would remove the need for the |
I think it would make more sense for the PyO3/chrono integration to live in the PyO3 repository than in the chrono repository: (1) the chrono side of this is relatively low-complexity compared to the PyO3 integration bits, (2) PyO3 is arguably a higher-level dependency than chrono and (3) I think a chrono integration provides more value to the average PyO3 user than a PyO3 integration would provide to the average chrono user (maybe this is a restatement of 2?). If we identify extra API surface that we need to expose to make that work well, that's certainly a worthy trade-off. |
Some parts taken from https://github.com/kangalioo/pyo3-chrono
Just curious, how did you find out about that? I did see two versions, one |
"owned" form basically means it will decrease the python reference count later. TBH the only way to know is to look at the docs for the C API - most return owned pointers, in this case it's a bit murky because the C API is a macro which just expands to the static item and PyO3 has to make a function instead. @pickfire, given the preference above to have this in PyO3, would you be interested in moving this to the PyO3 repo, perhaps after PyO3/pyo3#1588 merges? |
@@ -371,7 +371,7 @@ impl fmt::Debug for Of { | |||
/// (month, day of month and leap flag), | |||
/// which is an index to the `MDL_TO_OL` lookup table. | |||
#[derive(PartialEq, PartialOrd, Copy, Clone)] | |||
pub(super) struct Mdf(pub(super) u32); | |||
pub(crate) struct Mdf(pub(super) u32); |
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.
The thing I see is that Mdf
needs to be exposed, so I am not sure if it is a good tradeoff since the internals are being exposed. As well as mdf
function.
@@ -795,7 +795,7 @@ impl NaiveTime { | |||
} | |||
|
|||
/// Returns a triple of the hour, minute and second numbers. | |||
fn hms(&self) -> (u32, u32, u32) { | |||
pub(crate) fn hms(&self) -> (u32, u32, u32) { |
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.
And these to get internal values.
I am fine doing that, but I feel like that would lose the ability to be able to interface with underlying data directly. And we have to do extra code to transform it back to low level stuff. |
I see, that's a reasonable concern. I agree with @djc that usually I suspect that the Python ffi calls will dominate over slightly more efficient Rust code anyway. To help inform us, would you be willing to do some benchmarks to compare these implementations to some which don't use chrono internal APIs? (I'm happy to help you design them if needed.) If the difference is not significant I think we should proceed to move to PyO3, maybe leaving some issues here in chrono requesting access to these more efficient APIs (or variants of them which the chrono team are happy to commit to). If the difference matters, then I guess it's a choice for the chrono team whether to add APIs now to support the move, or to keep the PyO3 implementation here. |
I'd be happy to add API surface if that materially speeds up PyO3 access. |
I can think of two ways, one is to add Do I now close this pull request and wait for both pull requests on pyo3 and chrono to be merged then I continue the port to pyo3? |
I think it makes sense to close this pull request, and submit a PR to the pyo3 repo to add the chrono integration as well as a PR here for the necessary API expansions. For now, let's not do a feature flag or |
@pickfire I'll try to merge my PyO3 branch this weekend, it would then be possible for you to open both PyO3 and chrono PRs at the same time by using a git dependency on chrono. |
I have something that I wanted to do so I think I will only do this next month. |
No problem, this has been blocked on me for like a year already 😅 |
Hi everybody. I'm interested in an integration between pyo3 and chrono (and possibly chrono-tz too). If I understand correctly, your current idea is to add the integration in PyO3 rather than here, doing something similar to what was done in this PR, and if needed add things to the public api here, is that right? I'd like to help move things forward. I can start porting this PR to the PyO3 codebase (under a feature flag, in a @davidhewitt did I get this right? I read a lot of discussions/issues/PRs both here and on the PyO3 repo, I might have missed something |
I tried this again last week, but I noticed that this needs changes on both chrono and time crate, @djc do we have the luxury to be able to change time crate? We need Thanks for the ping @Psykopear, but I only get to work on this once last week and haven't touch it yet, but I will continue on this for now, not sure what help I need yet, but I guess maybe help me follow up on time crate? Now I am just slightly stuck at figuring out how to convert from |
good to hear that @pickfire .
I'm sorry I'm not sure I understand the problem here, does chrono (or the chrono integration for PyO3) requires the time crate? I know chrono used to be built upon time v0.1, but I don't see any reference of that in the current codebase (I ported this PR on top of the current
Yes I was working on that too while porting the PR, I ended up converting it where used (not sure it's the best way, but it works): let tz = self.offset().fix().into_py(py);
let tz: &PyTzInfo = tz.extract(py).unwrap(); Anyway if you are already working on it, I can still help with review and tests |
Moved from chronotope/chrono#542
@pickfire on main we no longer depend on time, on the 0.4.x branch we still do. I don't think there's a way to get new time 0.1 releases out, no. But for |
Moved from chronotope/chrono#542
Moved from chronotope/chrono#542
Some parts taken from https://github.com/kangalioo/pyo3-chrono
Note, I will continue working on this in few more days, I have something I wanted to experiment in the meantime.
cc @kangalioo
Implemented
PyDate <-> NaiveDate
PyTime <-> NaiveTime
PyDateTime <-> NaiveDateTime
PyDelta <-> Duration
(only implemented foroldtime
feature)(may confuse people sincePyDate <-> Date
PyDate
does not have timezone)PyTzInfo <-> Utc
PyTzInfo <-> FixedOffset
PyDateTime <-> DateTime
Thanks for contributing to chrono!
about adding the PR number)
we can't reintroduce it?