summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Smith <eric@trueblade.com>2009-11-29 17:40:57 (GMT)
committerEric Smith <eric@trueblade.com>2009-11-29 17:40:57 (GMT)
commitc4ab8339e9a966d9d8e601531489a5436d197f47 (patch)
tree3fb5a2fd6a2cd465bb376d864e3e6ee65d22eb31
parentccc690d650f0b784c5d0445d0c34d372d2d24ec3 (diff)
downloadcpython-c4ab8339e9a966d9d8e601531489a5436d197f47.zip
cpython-c4ab8339e9a966d9d8e601531489a5436d197f47.tar.gz
cpython-c4ab8339e9a966d9d8e601531489a5436d197f47.tar.bz2
Issue #3382: Make '%F' and float.__format__('F') convert results to upper case. Much of the patch came from Mark Dickinson.
-rw-r--r--Lib/test/formatfloat_testcases.txt24
-rw-r--r--Lib/test/test_complex.py19
-rw-r--r--Lib/test/test_float.py14
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/stringlib/formatter.h14
-rw-r--r--Objects/stringobject.c2
-rw-r--r--Objects/unicodeobject.c2
7 files changed, 59 insertions, 20 deletions
diff --git a/Lib/test/formatfloat_testcases.txt b/Lib/test/formatfloat_testcases.txt
index 4cf20aa..43ef040 100644
--- a/Lib/test/formatfloat_testcases.txt
+++ b/Lib/test/formatfloat_testcases.txt
@@ -81,6 +81,14 @@
%f 0.0000005001 -> 0.000001
%f 0.0000004999 -> 0.000000
+-- nans and infinities
+%f nan -> nan
+%f inf -> inf
+%f -infinity -> -inf
+%F nan -> NAN
+%F infinity -> INF
+%F -inf -> -INF
+
-- 'e' code formatting with explicit precision (>= 0). Output should
-- always have exactly the number of places after the point that were
-- requested.
@@ -202,6 +210,14 @@
%#.1e 123.4 -> 1.2e+02
%#.2e 0.0001357 -> 1.36e-04
+-- nans and infinities
+%e nan -> nan
+%e inf -> inf
+%e -infinity -> -inf
+%E nan -> NAN
+%E infinity -> INF
+%E -inf -> -INF
+
-- 'g' code formatting.
-- zeros
@@ -314,6 +330,14 @@
%#.5g 234.56 -> 234.56
%#.6g 234.56 -> 234.560
+-- nans and infinities
+%g nan -> nan
+%g inf -> inf
+%g -infinity -> -inf
+%G nan -> NAN
+%G infinity -> INF
+%G -inf -> -INF
+
-- for repr formatting see the separate test_short_repr test in
-- test_float.py. Not all platforms use short repr for floats.
diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py
index a192ec4..a2f4ed5 100644
--- a/Lib/test/test_complex.py
+++ b/Lib/test/test_complex.py
@@ -539,6 +539,25 @@ class ComplexTest(unittest.TestCase):
# make sure everything works in ''.format()
self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*')
+ # issue 3382: 'f' and 'F' with inf's and nan's
+ self.assertEqual('{0:f}'.format(INF+0j), 'inf+0.000000j')
+ self.assertEqual('{0:F}'.format(INF+0j), 'INF+0.000000j')
+ self.assertEqual('{0:f}'.format(-INF+0j), '-inf+0.000000j')
+ self.assertEqual('{0:F}'.format(-INF+0j), '-INF+0.000000j')
+ self.assertEqual('{0:f}'.format(complex(INF, INF)), 'inf+infj')
+ self.assertEqual('{0:F}'.format(complex(INF, INF)), 'INF+INFj')
+ self.assertEqual('{0:f}'.format(complex(INF, -INF)), 'inf-infj')
+ self.assertEqual('{0:F}'.format(complex(INF, -INF)), 'INF-INFj')
+ self.assertEqual('{0:f}'.format(complex(-INF, INF)), '-inf+infj')
+ self.assertEqual('{0:F}'.format(complex(-INF, INF)), '-INF+INFj')
+ self.assertEqual('{0:f}'.format(complex(-INF, -INF)), '-inf-infj')
+ self.assertEqual('{0:F}'.format(complex(-INF, -INF)), '-INF-INFj')
+
+ self.assertEqual('{0:f}'.format(complex(NAN, 0)), 'nan+0.000000j')
+ self.assertEqual('{0:F}'.format(complex(NAN, 0)), 'NAN+0.000000j')
+ self.assertEqual('{0:f}'.format(complex(NAN, NAN)), 'nan+nanj')
+ self.assertEqual('{0:F}'.format(complex(NAN, NAN)), 'NAN+NANj')
+
def test_main():
test_support.run_unittest(ComplexTest)
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 4e918fb..3ad1402 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -309,6 +309,14 @@ class IEEEFormatTestCase(unittest.TestCase):
self.assertRaises(ValueError, format, 1e-100, format_spec)
self.assertRaises(ValueError, format, -1e-100, format_spec)
+ # issue 3382: 'f' and 'F' with inf's and nan's
+ self.assertEqual('{0:f}'.format(INF), 'inf')
+ self.assertEqual('{0:F}'.format(INF), 'INF')
+ self.assertEqual('{0:f}'.format(-INF), '-inf')
+ self.assertEqual('{0:F}'.format(-INF), '-INF')
+ self.assertEqual('{0:f}'.format(NAN), 'nan')
+ self.assertEqual('{0:F}'.format(NAN), 'NAN')
+
@unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
"test requires IEEE 754 doubles")
def test_format_testfile(self):
@@ -321,8 +329,10 @@ class IEEEFormatTestCase(unittest.TestCase):
lhs, rhs = map(str.strip, line.split('->'))
fmt, arg = lhs.split()
- self.assertEqual(fmt % float(arg), rhs)
- self.assertEqual(fmt % -float(arg), '-' + rhs)
+ arg = float(arg)
+ self.assertEqual(fmt % arg, rhs)
+ if not math.isnan(arg) and copysign(1.0, arg) > 0.0:
+ self.assertEqual(fmt % -arg, '-' + rhs)
def test_issue5864(self):
self.assertEquals(format(123.456, '.4'), '123.5')
diff --git a/Misc/NEWS b/Misc/NEWS
index 2d6b7f0..e5c8626 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1
Core and Builtins
-----------------
+- Issue #3382: 'F' formatting for float and complex now convert the
+ result to upper case. This only affects 'inf' and 'nan', since 'f'
+ no longer converts to 'g' for large values.
+
- Remove switch from "%f" formatting to "%g" formatting for floats
larger than 1e50 in absolute value.
diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h
index f09578f..f4a3ea3 100644
--- a/Objects/stringlib/formatter.h
+++ b/Objects/stringlib/formatter.h
@@ -937,13 +937,6 @@ format_float_internal(PyObject *value,
format the result. We take care of that later. */
type = 'g';
-#if PY_VERSION_HEX < 0x0301000
- /* 'F' is the same as 'f', per the PEP */
- /* This is no longer the case in 3.x */
- if (type == 'F')
- type = 'f';
-#endif
-
val = PyFloat_AsDouble(value);
if (val == -1.0 && PyErr_Occurred())
goto done;
@@ -1128,13 +1121,6 @@ format_complex_internal(PyObject *value,
format the result. We take care of that later. */
type = 'g';
-#if PY_VERSION_HEX < 0x03010000
- /* This is no longer the case in 3.x */
- /* 'F' is the same as 'f', per the PEP */
- if (type == 'F')
- type = 'f';
-#endif
-
if (precision < 0)
precision = default_precision;
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 6636b9a..02aabf2 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -4966,8 +4966,6 @@ PyString_Format(PyObject *format, PyObject *args)
case 'F':
case 'g':
case 'G':
- if (c == 'F')
- c = 'f';
temp = formatfloat(v, flags, prec, c);
if (temp == NULL)
goto error;
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 2fa004e..e85b20f 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -8809,8 +8809,6 @@ PyObject *PyUnicode_Format(PyObject *format,
case 'F':
case 'g':
case 'G':
- if (c == 'F')
- c = 'f';
temp = formatfloat(v, flags, prec, c);
if (temp == NULL)
goto onError;