-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
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
bpo-45995: add "z" format specifer to coerce negative 0 to zero #30049
Conversation
97a033b
to
8ff811f
Compare
Modules/_decimal/_decimal.c
Outdated
char *z_start = strchr(fmt, 'z'); | ||
if (z_start != NULL) { | ||
no_neg_0 = 1; | ||
size_t z_index = z_start - fmt; | ||
if (fmt_copy == NULL) { | ||
fmt = fmt_copy = dec_strdup(fmt, size); | ||
if (fmt_copy == NULL) { | ||
return NULL; | ||
} | ||
} | ||
memmove(fmt_copy + z_index, fmt_copy + z_index + 1, size - z_index); | ||
size -= 1; |
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.
if PR #29438 lands, then detection of the "z" option can be incorporated into our forked mpd_parse_fmt_str_ex()
, rather than this preprocessing of the format string
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 think it's the case that one way or the other, the format spec is going to need to be completely parsed to figure out if a given 'z' is used for no_neg_0.
This PR is stale because it has been open for 30 days with no activity. |
Removing the stale label; discussion is ongoing on the bug tracker. |
1bfb289
to
bb4d5f1
Compare
Update: the PEP has been accepted - https://discuss.python.org/t/accepting-pep-682-format-specifier-for-signed-zero/14088 We should aim to get this reviewed and in by the next (and final) alpha release of 3.11, due April 5th. |
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.
Hi @belm0. Here's a first-pass review; apologies for taking so long to get to this.
Most of the comments are nitpick-level. The big exception is the Decimal code, where I think there's still significant work to do.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
@ericvsmith: if you have any bandwidth to look over the code at some point before the first 3.11 beta, I'd appreciate your input. |
Misc/NEWS.d/next/Library/2021-12-14-13-15-41.bpo-45995.Am9pNL.rst
Outdated
Show resolved
Hide resolved
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.
Thank you for the thorough review!
I'm bogged down a bit and it may take a week or so to reconcile the comments.
Hoping to get this merged for the next (final) alpha.
3.11.0 alpha 7: Tuesday, 2022-04-05
3.11.0 beta 1: Friday, 2022-05-06
This covers str.format() and f-strings. Old-style string interpolation is not supported. TODO: Decimal support
if (no_neg_0 && mpd_isnegative(mpd) && !mpd_isspecial(mpd)) { | ||
/* Round into a temporary (carefully mirroring the rounding | ||
of mpd_qformat_spec()), and check if the result is negative zero. | ||
If so, clear the sign and format the resulting positive zero. */ |
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.
An insight I had recently was that, once negative zero is confirmed somehow, producing the correct output is only a matter of formatting positive zero (which cannot be affected by directed rounding, etc.).
As for how to detect negative zero, the options are: 1) round independently of the format function, or 2) analyze the string result of the format function (as Mark suggested). I found the former easier to manage, since it's a matter of duplicating a small amount of proven mpd library code, and is relatively straightforward to test. In contrast, analyzing the format output involves writing a new and perfectly-correct regex or parser, and imagining all the format spec edge cases to test it with.
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.
Here's a second-pass review. We're getting there, but there are still a couple of bugs to resolve.
Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
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.
Thank you for the updates! This looks ready to merge to me. I've been running some automated tests that cover a wide variety of combinations, and haven't yet managed to break this. :-)
A bit off-topic: I do think we're introducing some DRY-type technical debt into _decimal.c
, though for this PR I don't see an easy alternative. For the future, there's scope for some cleanup after lifting the formatting machinery from libmpdec to _decimal.c
. That's for another day, though.
Misc/NEWS.d/next/Library/2021-12-14-13-15-41.bpo-45995.Am9pNL.rst
Outdated
Show resolved
Hide resolved
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.
Other than possibly adding a credit in the blurb, this looks good to me.
using file edit from the github UI appears to have angered CLA bot and bedevere |
I think it's related to the bpo to github issues migration. I'll see what I can figure out. |
The "CLA Signing" check doesn't seem to be required for merging. Given that we know that CLA signing has occurred, I think we should be okay to merge. I've reported the failure to @ambv. |
The implementation of PEP 682 was completed in python/cpython#30049.
The implementation of PEP 682 was completed in python/cpython#30049.
This option coerces negative zero into zero after rounding to the format precision.
Covers formatting of standard fraction types (
float
,Decimal
,complex
) viastr.format()
, built-informat()
, and f-strings. Old-style string interpolationis not supported.
https://www.python.org/dev/peps/pep-0682/
https://bugs.python.org/issue45995