Commit 741191f1 authored by Eric Smith's avatar Eric Smith

Issue #3382. float 'F' formatting no longer maps to 'f'. This only affects nan and inf.

parent 5776c162
...@@ -415,7 +415,8 @@ The available presentation types for floating point and decimal values are: ...@@ -415,7 +415,8 @@ The available presentation types for floating point and decimal values are:
| ``'f'`` | Fixed point. Displays the number as a fixed-point | | ``'f'`` | Fixed point. Displays the number as a fixed-point |
| | number. | | | number. |
+---------+----------------------------------------------------------+ +---------+----------------------------------------------------------+
| ``'F'`` | Fixed point. Same as ``'f'``. | | ``'F'`` | Fixed point. Same as ``'f'``, but converts ``nan`` to |
| | ``NAN`` and ``inf`` to ``INF``. |
+---------+----------------------------------------------------------+ +---------+----------------------------------------------------------+
| ``'g'`` | General format. This prints the number as a fixed-point | | ``'g'`` | General format. This prints the number as a fixed-point |
| | number, unless the number is too large, in which case | | | number, unless the number is too large, in which case |
......
...@@ -507,6 +507,24 @@ class ComplexTest(unittest.TestCase): ...@@ -507,6 +507,24 @@ class ComplexTest(unittest.TestCase):
# make sure everything works in ''.format() # make sure everything works in ''.format()
self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*')
# issue 3382
self.assertEqual(format(complex(NAN, NAN), 'f'), 'nan+nanj')
self.assertEqual(format(complex(1, NAN), 'f'), '1.000000+nanj')
self.assertEqual(format(complex(NAN, 1), 'f'), 'nan+1.000000j')
self.assertEqual(format(complex(NAN, -1), 'f'), 'nan-1.000000j')
self.assertEqual(format(complex(NAN, NAN), 'F'), 'NAN+NANj')
self.assertEqual(format(complex(1, NAN), 'F'), '1.000000+NANj')
self.assertEqual(format(complex(NAN, 1), 'F'), 'NAN+1.000000j')
self.assertEqual(format(complex(NAN, -1), 'F'), 'NAN-1.000000j')
self.assertEqual(format(complex(INF, INF), 'f'), 'inf+infj')
self.assertEqual(format(complex(1, INF), 'f'), '1.000000+infj')
self.assertEqual(format(complex(INF, 1), 'f'), 'inf+1.000000j')
self.assertEqual(format(complex(INF, -1), 'f'), 'inf-1.000000j')
self.assertEqual(format(complex(INF, INF), 'F'), 'INF+INFj')
self.assertEqual(format(complex(1, INF), 'F'), '1.000000+INFj')
self.assertEqual(format(complex(INF, 1), 'F'), 'INF+1.000000j')
self.assertEqual(format(complex(INF, -1), 'F'), 'INF-1.000000j')
def test_main(): def test_main():
support.run_unittest(ComplexTest) support.run_unittest(ComplexTest)
......
...@@ -320,6 +320,12 @@ class FormatTestCase(unittest.TestCase): ...@@ -320,6 +320,12 @@ class FormatTestCase(unittest.TestCase):
self.assertRaises(ValueError, format, 1e-100, format_spec) self.assertRaises(ValueError, format, 1e-100, format_spec)
self.assertRaises(ValueError, format, -1e-100, format_spec) self.assertRaises(ValueError, format, -1e-100, format_spec)
# issue 3382
self.assertEqual(format(NAN, 'f'), 'nan')
self.assertEqual(format(NAN, 'F'), 'NAN')
self.assertEqual(format(INF, 'f'), 'inf')
self.assertEqual(format(INF, 'F'), 'INF')
@unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
"test requires IEEE 754 doubles") "test requires IEEE 754 doubles")
def test_format_testfile(self): def test_format_testfile(self):
......
...@@ -779,6 +779,14 @@ class UnicodeTest( ...@@ -779,6 +779,14 @@ class UnicodeTest(
return '\u1234' return '\u1234'
self.assertEqual('%s' % Wrapper(), '\u1234') self.assertEqual('%s' % Wrapper(), '\u1234')
# issue 3382
NAN = float('nan')
INF = float('inf')
self.assertEqual('%f' % NAN, 'nan')
self.assertEqual('%F' % NAN, 'NAN')
self.assertEqual('%f' % INF, 'inf')
self.assertEqual('%F' % INF, 'INF')
@support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR') @support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
def test_format_float(self): def test_format_float(self):
# should not format with a comma, but always with C locale # should not format with a comma, but always with C locale
......
...@@ -12,6 +12,10 @@ What's New in Python 3.1 beta 1? ...@@ -12,6 +12,10 @@ What's New in Python 3.1 beta 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #3382: float.__format__, complex.__format__, and %-formatting
no longer map 'F' to 'f'. Because of issue #5859 (below), this only
affects nan -> NAN and inf -> INF.
- Issue #5799: ntpath (ie, os.path on Windows) fully supports UNC pathnames - Issue #5799: ntpath (ie, os.path on Windows) fully supports UNC pathnames
in all operations, including splitdrive, split, etc. splitunc() now issues in all operations, including splitdrive, split, etc. splitunc() now issues
a PendingDeprecation warning. a PendingDeprecation warning.
......
...@@ -920,10 +920,6 @@ format_float_internal(PyObject *value, ...@@ -920,10 +920,6 @@ format_float_internal(PyObject *value,
format the result. We take care of that later. */ format the result. We take care of that later. */
type = 'g'; type = 'g';
/* 'F' is the same as 'f', per the PEP */
if (type == 'F')
type = 'f';
val = PyFloat_AsDouble(value); val = PyFloat_AsDouble(value);
if (val == -1.0 && PyErr_Occurred()) if (val == -1.0 && PyErr_Occurred())
goto done; goto done;
...@@ -939,8 +935,15 @@ format_float_internal(PyObject *value, ...@@ -939,8 +935,15 @@ format_float_internal(PyObject *value,
#if PY_VERSION_HEX < 0x03010000 #if PY_VERSION_HEX < 0x03010000
/* 3.1 no longer converts large 'f' to 'g'. */ /* 3.1 no longer converts large 'f' to 'g'. */
if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) if (fabs(val) >= 1e50)
switch (type) {
case 'f':
type = 'g'; type = 'g';
break;
case 'F':
type = 'G';
break;
}
#endif #endif
/* Cast "type", because if we're in unicode we need to pass a /* Cast "type", because if we're in unicode we need to pass a
...@@ -1114,10 +1117,6 @@ format_complex_internal(PyObject *value, ...@@ -1114,10 +1117,6 @@ format_complex_internal(PyObject *value,
format the result. We take care of that later. */ format the result. We take care of that later. */
type = 'g'; type = 'g';
/* 'F' is the same as 'f', per the PEP */
if (type == 'F')
type = 'f';
if (precision < 0) if (precision < 0)
precision = default_precision; precision = default_precision;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment