-
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
implement Decimal to rust_decimal conversions #3016
Conversation
I created the PR as suggested by @davidhewitt in #2774 to start the conversation. I added an initial benchmark but I'm not sure if it's sufficient to start. The results were:
not sure why I had that trailing open paren. The tests fail because I haven't written any docs yet. I've still got to address @adamreichold's feedback as well but I figured I'd start with the benchmarks to see if it makes sense and if not talk to CPython upstream about exposing an API. If the benchmarks are okay then I'll work in parallel. Add the necessary bits to raise this to completion while getting an API exposed in CPython. |
Personally, I think that independently of the kind of (modernish) system this was run on, that the performance is reasonable and would have this than have it not, understanding that we can always improve things if better CPython API become available. |
IMO we should only have these conversions if they're better than what a user could naively write themselves. Python's decimal has no C api, so this isn't the case here. |
But why force the user into reinventing this if we can solve the problem once for everybody? As long as it is the best possible solution. And if a better way comes along, we can improve things in a single place and everyone benefits immediately. |
@mejrs My thought process for this PR was that decimal is part of the stdlib as a type. I don't think it makes sense to add every part of stdlib but looking through most of the types (I'm counting the types under the numerical as well) are covered except for big integers which is what this aims to cover. |
I'm not actively catching up on the project, so I'm not sure, but is there any other module where we support conversion between some Rust library and Python object which doesn't have C-API? If so, having this would be OK. But I'm not very convinced with this string-based conversion... If we can use tuple instead, it would be faster. |
I keep going back and forth on this line of thinking. I think ultimately the types with a C-API are not significantly different except that we wrap away the I do agree with @adamreichold's argument that getting this once right here is better for the ecosystem than forcing fragmentation. Also we essentially use Python APIs for Although I still agree it would be great to have a native conversion provided upstream, if there is willingness.
It's not clear to me which conversion options are available, however it would be good to sense-check what we're offering here is the most efficient. |
Also of note is that we do have similar precedent with support for converting |
So the reason I went with the string over the tuple is that the Python tuple doesn't map to the Rust interface nicely. The Python tuple documented at https://docs.python.org/3/library/decimal.html#decimal.Decimal says its
We'd have a couple of weird corner cases with Infinity and NaN via as_tuple as well.
Now from the Rust side the closest to the tuple interface is probably
So ultimately if that's approach you'd like me to take I think I'd steer towards |
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 have any preference for one implementation over the other. If you're willing to experiment, it would be good to compare from_str_radix
and from_str_exact
(if those are the candidates we're looking at), to see if there's any meaningful implementation and performance differences.
@cardoe |
02ddcae
to
65f3f8d
Compare
I believe this addresses all the feedback thus far and could be the first commit considered for a full review / inclusion. |
023d669
to
2655a61
Compare
I think this fixed the MSRV issue. |
I've just got an M1 based Mac to test on right now so the MSRV won't build on here so fingers crossed really. |
ee2466f
to
c029ed0
Compare
Hello, I'll do my best to review this tomorrow. A bit behind on OSS this week, had a sick family. We're better now finally :) |
src/conversions/rust_decimal.rs
Outdated
#![cfg_attr(docsrs, cfg_attr(docsrs, doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"rust_decimal\"] }")))] | ||
#![cfg_attr( | ||
not(docsrs), | ||
doc = "pyo3 = { version = \"*\", features = [\"rust_decimal\"] }" |
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.
Maybe not encourage version = "*"
but use version = ...
to indicate something to replace?
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'll add a comment above like:
pyo3/src/conversions/anyhow.rs
Line 31 in ebd417c
doc = "pyo3 = { version = \"*\", features = [\"anyhow\"] }" |
pyo3/src/conversions/chrono.rs
Line 21 in ebd417c
doc = "pyo3 = { version = \"*\", features = [\"chrono\"] }" |
The others don't have one. I followed num-bigint as an example when writing this.
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.
Yep fine to leave like this for now. When we update MSRV above 1.54 we can simplify this and just have the CARGO_PKG_VERSION
embedded everywhere.
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 am sorry for re-opening, but I do think @birkenfeld's suggestion of using version = ...
instead is better. As it stands now, I get the comment about *
on docs.rs even though docs.rs uses CARGO_PKG_VERSION
and hence there is no *
in sight.
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.
Sure. I was just trying to match the style of the rest of the code base.
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 version specification looks good now but it looks like you did not remove the comment 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.
Took the liberty of amending that commit and will merge this now as I think anything has been addressed now. Any other improvements can be follow-ups.
Take you time. Family first. OSS is the shoulder monkey that never goes away for better or worse. I'm not in any rush on this. I was playing around with a Python code base and grumping at "type whispering" biting me on something and though I would try to lift part of the code base into Rust and looked for |
First time contributor has agreed to the new licensing scheme. |
I believe I've addressed all the PR feedback. Please let me know what I can do going forward. The current GitHub actions failures are happening for me locally on my machine with the latest main commit as well. |
32540a8
to
c275a9a
Compare
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.
Sorry doing another round on this.
src/conversions/rust_decimal.rs
Outdated
#![cfg_attr(docsrs, cfg_attr(docsrs, doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"rust_decimal\"] }")))] | ||
#![cfg_attr( | ||
not(docsrs), | ||
doc = "pyo3 = { version = \"*\", features = [\"rust_decimal\"] }" |
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 am sorry for re-opening, but I do think @birkenfeld's suggestion of using version = ...
instead is better. As it stands now, I get the comment about *
on docs.rs even though docs.rs uses CARGO_PKG_VERSION
and hence there is no *
in sight.
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.
There still is the left-over comment concerning the *
version specification, otherwise I think this is good to land. Thanks for keeping at it!
Implement conversion between rust_decimal::Decimal and decimal.Decimal from Python's stdlib. The C API does not appear to be exposed on the Python side so we need to call into it via Python.
bors r+ |
3016: implement Decimal to rust_decimal conversions r=adamreichold a=cardoe Implement conversion between rust_decimal::Decimal and decimal.Decimal from Python's stdlib. The C API does not appear to be exposed on the Python side so we need to call into it via Python. Implements #2774 Co-authored-by: Doug Goldstein <cardoe@cardoe.com>
Build failed: |
bors retry |
Build succeeded: |
Implement conversion between rust_decimal::Decimal and decimal.Decimal from Python's stdlib. The C API does not appear to be exposed on the Python side so we need to call into it via Python.
Implements #2774