You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add alternate float formatting styles to new-style formatting. #51343
Python's old-style formatting supports the use of an alternative form
(specified by including a '#' in the format) for 'e', 'f' and 'g'
formatting:
Python 3.2a0 (py3k:75275:75276, Oct 7 2009, 20:26:36)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> '%.17g'%1.2
'1.2'
>>> '%#.17g'%1.2
'1.2000000000000000'
New-style formatting doesn't currently support this:
>>> format(1.2, '#.17g')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Alternate form (#) not allowed in float format specifier
To aid migration from old-style to new-style formatting, it might be worth
adding the alternate forms. At least the float, complex and Decimal types
would be affected.
Just for reference, the effect of the alternative style is explained
succinctly in the C99 standard (well, the N1256 draft, anyway):
"For a, A, e, E, f, F, g, and G conversions, the result of converting a
floating-point number always contains a decimal-point character, even if
no digits follow it. (Normally, a decimal-point character appears in the
result of these conversions only if a digit follows it.) For g and G
conversions, trailing zeros are not removed from the result. For other
conversions, the behavior is undefined."
I do not believe that this is covered by the moratorium. It's important for 3.x success to get new string formatting to its highest state of usability. Matching published standards and practices(i.e. C99) and improving ability to convert from old-style to new style are both very helpful in this regard.
But I'm uploading it here anyway so that it doesn't get lost. I'll be refining the patch over the next several days. The patch covers float, complex, and decimal.
Thanks to:
Eric Groo
Vlad Korolev
Bob Schmertz
Owen Martin
I haven't done a full review, but this looks good at first glance.
For '#g' formatting on the Decimal type, I wonder whether the patch gives the right semantics. E.g., should
format(Decimal('1.23'), '#.6g')
give '1.23' or '1.23000'? For the float type, the '#.<precision>g' formatting has the property that <precision> digits are always returned, and I think this may be what we want here. I'm not sure, though.
Apart from this, the rest of the patch looks good, and all tests pass on my machine. (Well, except for test_urllib2_localnet, but I'm pretty sure that failure is unrelated.)
I hadn't realized the use_alt_formatting stuff was already present in Python/pystrtod.c.
I agree that:
format(Decimal('1.23'), '#.6g')
should give '1.23000', just as:
format(1.23, '#.6g')
does.
I'll work on fixing the patch, although if I don't get to it in the next few days I'll commit the existing patch and open another issue, just to make sure this gets in before the beta.
I'm going to go ahead and close this. Alternate formatting was added to float and complex. I think leaving this issue open just confuses whether or not that support was added. I know I had to go back and double check.
Since decimal never participated in %-formatting, there are no "migration to .format()" issues with it. I agree that it's unlikely anyone would want it, and if we want to add it, it would be a new, separate issue.
It looks like this change has not been applied to Python 2.7. Do we have any chance of getting it to 2.7?
So I'm unsure if anyone is actually using alternate formatting.
The "alternative form" is my favorite, and I think that "%#g" should be the default format for general floating-point values in numerical applications. That is why I miss this feature in Python 2.7 so much.
Activity
mdickinson commentedon Oct 9, 2009
Python's old-style formatting supports the use of an alternative form
(specified by including a '#' in the format) for 'e', 'f' and 'g'
formatting:
New-style formatting doesn't currently support this:
To aid migration from old-style to new-style formatting, it might be worth
adding the alternate forms. At least the float, complex and Decimal types
would be affected.
ericvsmith commentedon Oct 9, 2009
I'm adding 2.7. Since 2.7 and 3.2 share the same code base, I'd rather
add it to both if we're going to do it at all.
mdickinson commentedon Oct 9, 2009
Just for reference, the effect of the alternative style is explained
succinctly in the C99 standard (well, the N1256 draft, anyway):
"For a, A, e, E, f, F, g, and G conversions, the result of converting a
floating-point number always contains a decimal-point character, even if
no digits follow it. (Normally, a decimal-point character appears in the
result of these conversions only if a digit follows it.) For g and G
conversions, trailing zeros are not removed from the result. For other
conversions, the behavior is undefined."
ericvsmith commentedon Dec 2, 2009
When and if this is implemented, there's a test in test_float.py that
needs to be deleted. Search on "if not '#' in fmt:", added in r76632.
terryjreedy commentedon Aug 9, 2010
I believe this is covered by the PEP-3003 3.2 change moratorium.
rhettinger commentedon Aug 11, 2010
I do not believe that this is covered by the moratorium. It's important for 3.x success to get new string formatting to its highest state of usability. Matching published standards and practices(i.e. C99) and improving ability to convert from old-style to new style are both very helpful in this regard.
ericvsmith commentedon Nov 20, 2010
Also note that if # is added for float and Decimal, it should be added for complex. My Bug Day sprint group will have a patch for this shortly.
ericvsmith commentedon Nov 21, 2010
This is the patch developed today at the DCPython sprint. I have not reviewed it very well. I know that at least:
But I'm uploading it here anyway so that it doesn't get lost. I'll be refining the patch over the next several days. The patch covers float, complex, and decimal.
Thanks to:
Eric Groo
Vlad Korolev
Bob Schmertz
Owen Martin
ericvsmith commentedon Nov 21, 2010
Updated patch. I'm pretty happy with this one and will commit it after review.
mdickinson commentedon Nov 21, 2010
I haven't done a full review, but this looks good at first glance.
For '#g' formatting on the Decimal type, I wonder whether the patch gives the right semantics. E.g., should
format(Decimal('1.23'), '#.6g')
give '1.23' or '1.23000'? For the float type, the '#.<precision>g' formatting has the property that <precision> digits are always returned, and I think this may be what we want here. I'm not sure, though.
mdickinson commentedon Nov 21, 2010
I think the change below is sufficient if we decide that the '#g' formatting should always have the given number of significant digits.
mdickinson commentedon Nov 21, 2010
Gah. That doesn't work for zeros, though.
Apart from this, the rest of the patch looks good, and all tests pass on my machine. (Well, except for test_urllib2_localnet, but I'm pretty sure that failure is unrelated.)
I hadn't realized the use_alt_formatting stuff was already present in Python/pystrtod.c.
ericvsmith commentedon Nov 21, 2010
I didn't realize it either, or I would have done this patch months ago. But of course it's needed for %-formatting.
I'll consider the 'g' case and see what I come up with.
ericvsmith commentedon Nov 21, 2010
I agree that:
format(Decimal('1.23'), '#.6g')
should give '1.23000', just as:
format(1.23, '#.6g')
does.
I'll work on fixing the patch, although if I don't get to it in the next few days I'll commit the existing patch and open another issue, just to make sure this gets in before the beta.
ericvsmith commentedon Nov 25, 2010
Checked in r86751. I'm leaving this open until I fix the remaining issue with '#g' for Decimal.
BreamoreBoy commentedon Apr 1, 2013
@eric looks as if the bulk of the work has been done so would you like to dot the i's and cross the t's?
skrah commentedon May 23, 2014
This might be out of date: _decimal has never implemented alternate
formatting and so far there have been no reported issues.
Another data point: Go apparently implements alternate formatting
only for octal, hex and strings:
http://golang.org/pkg/fmt/
So I'm unsure if anyone is actually using alternate formatting.
I think complaints about 2-to-3 porting problems should have
surfaced by now.
rhettinger commentedon May 24, 2014
That makes sense. Any further effort should wait until there is known demand. Otherwise, we risk growing the API with codes that aren't used.
ericvsmith commentedon May 24, 2014
I'm going to go ahead and close this. Alternate formatting was added to float and complex. I think leaving this issue open just confuses whether or not that support was added. I know I had to go back and double check.
Since decimal never participated in %-formatting, there are no "migration to .format()" issues with it. I agree that it's unlikely anyone would want it, and if we want to add it, it would be a new, separate issue.
SeungbeomKim commentedon May 29, 2015
It looks like this change has not been applied to Python 2.7. Do we have any chance of getting it to 2.7?
The "alternative form" is my favorite, and I think that "%#g" should be the default format for general floating-point values in numerical applications. That is why I miss this feature in Python 2.7 so much.
terryjreedy commentedon May 30, 2015
New features only go in new versions.