From ad088ca5c6adc4a107411cad62b83f5c6e06b5ed Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 29 May 2020 06:46:54 -0700 Subject: [PATCH] bpo-40780: Fix failure of _Py_dg_dtoa to remove trailing zeros (GH-20435) (GH-20514) * Fix failure of _Py_dg_dtoa to remove trailing zeros * Add regression test and news entry * Add explanation about why it's safe to strip trailing zeros * Make code safer, clean up comments, add change note at top of file * Nitpick: avoid implicit int-to-float conversion in tests (cherry picked from commit 895c9c1d438367722f74f437fda96767d770662b) Co-authored-by: Mark Dickinson --- Lib/test/test_format.py | 11 +++++++++++ .../2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst | 2 ++ Python/dtoa.c | 11 +++++++++++ 3 files changed, 24 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 4559cd5623e..e9e5bb9cf00 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -484,6 +484,17 @@ class FormatTest(unittest.TestCase): with self.assertRaises(ValueError) as cm: format(c, ".%sf" % (INT_MAX + 1)) + def test_g_format_has_no_trailing_zeros(self): + # regression test for bugs.python.org/issue40780 + self.assertEqual("%.3g" % 1505.0, "1.5e+03") + self.assertEqual("%#.3g" % 1505.0, "1.50e+03") + + self.assertEqual(format(1505.0, ".3g"), "1.5e+03") + self.assertEqual(format(1505.0, "#.3g"), "1.50e+03") + + self.assertEqual(format(12300050.0, ".6g"), "1.23e+07") + self.assertEqual(format(12300050.0, "#.6g"), "1.23000e+07") + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst new file mode 100644 index 00000000000..ed6020c2e23 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-26-17-43-58.bpo-40780.3Ckdgm.rst @@ -0,0 +1,2 @@ +Fix a corner case where g-style string formatting of a float failed to +remove trailing zeros. diff --git a/Python/dtoa.c b/Python/dtoa.c index 822adc61296..e629b296426 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -64,6 +64,9 @@ * 7. _Py_dg_strtod has been modified so that it doesn't accept strings with * leading whitespace. * + * 8. A corner case where _Py_dg_dtoa didn't strip trailing zeros has been + * fixed. (bugs.python.org/issue40780) + * ***************************************************************/ /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg @@ -2563,6 +2566,14 @@ _Py_dg_dtoa(double dd, int mode, int ndigits, } ++*s++; } + else { + /* Strip trailing zeros. This branch was missing from the + original dtoa.c, leading to surplus trailing zeros in + some cases. See bugs.python.org/issue40780. */ + while (s > s0 && s[-1] == '0') { + --s; + } + } break; } }