Skip to content

Commit c4ab833

Browse files
committed
Issue #3382: Make '%F' and float.__format__('F') convert results to upper case. Much of the patch came from Mark Dickinson.
1 parent ccc690d commit c4ab833

7 files changed

Lines changed: 59 additions & 20 deletions

File tree

‎Lib/test/formatfloat_testcases.txt‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@
8181
%f 0.0000005001 -> 0.000001
8282
%f 0.0000004999 -> 0.000000
8383

84+
-- nans and infinities
85+
%f nan -> nan
86+
%f inf -> inf
87+
%f -infinity -> -inf
88+
%F nan -> NAN
89+
%F infinity -> INF
90+
%F -inf -> -INF
91+
8492
-- 'e' code formatting with explicit precision (>= 0). Output should
8593
-- always have exactly the number of places after the point that were
8694
-- requested.
@@ -202,6 +210,14 @@
202210
%#.1e 123.4 -> 1.2e+02
203211
%#.2e 0.0001357 -> 1.36e-04
204212

213+
-- nans and infinities
214+
%e nan -> nan
215+
%e inf -> inf
216+
%e -infinity -> -inf
217+
%E nan -> NAN
218+
%E infinity -> INF
219+
%E -inf -> -INF
220+
205221
-- 'g' code formatting.
206222

207223
-- zeros
@@ -314,6 +330,14 @@
314330
%#.5g 234.56 -> 234.56
315331
%#.6g 234.56 -> 234.560
316332

333+
-- nans and infinities
334+
%g nan -> nan
335+
%g inf -> inf
336+
%g -infinity -> -inf
337+
%G nan -> NAN
338+
%G infinity -> INF
339+
%G -inf -> -INF
340+
317341
-- for repr formatting see the separate test_short_repr test in
318342
-- test_float.py. Not all platforms use short repr for floats.
319343

‎Lib/test/test_complex.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,25 @@ def test_format(self):
539539
# make sure everything works in ''.format()
540540
self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*')
541541

542+
# issue 3382: 'f' and 'F' with inf's and nan's
543+
self.assertEqual('{0:f}'.format(INF+0j), 'inf+0.000000j')
544+
self.assertEqual('{0:F}'.format(INF+0j), 'INF+0.000000j')
545+
self.assertEqual('{0:f}'.format(-INF+0j), '-inf+0.000000j')
546+
self.assertEqual('{0:F}'.format(-INF+0j), '-INF+0.000000j')
547+
self.assertEqual('{0:f}'.format(complex(INF, INF)), 'inf+infj')
548+
self.assertEqual('{0:F}'.format(complex(INF, INF)), 'INF+INFj')
549+
self.assertEqual('{0:f}'.format(complex(INF, -INF)), 'inf-infj')
550+
self.assertEqual('{0:F}'.format(complex(INF, -INF)), 'INF-INFj')
551+
self.assertEqual('{0:f}'.format(complex(-INF, INF)), '-inf+infj')
552+
self.assertEqual('{0:F}'.format(complex(-INF, INF)), '-INF+INFj')
553+
self.assertEqual('{0:f}'.format(complex(-INF, -INF)), '-inf-infj')
554+
self.assertEqual('{0:F}'.format(complex(-INF, -INF)), '-INF-INFj')
555+
556+
self.assertEqual('{0:f}'.format(complex(NAN, 0)), 'nan+0.000000j')
557+
self.assertEqual('{0:F}'.format(complex(NAN, 0)), 'NAN+0.000000j')
558+
self.assertEqual('{0:f}'.format(complex(NAN, NAN)), 'nan+nanj')
559+
self.assertEqual('{0:F}'.format(complex(NAN, NAN)), 'NAN+NANj')
560+
542561
def test_main():
543562
test_support.run_unittest(ComplexTest)
544563

‎Lib/test/test_float.py‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,14 @@ def test_format(self):
309309
self.assertRaises(ValueError, format, 1e-100, format_spec)
310310
self.assertRaises(ValueError, format, -1e-100, format_spec)
311311

312+
# issue 3382: 'f' and 'F' with inf's and nan's
313+
self.assertEqual('{0:f}'.format(INF), 'inf')
314+
self.assertEqual('{0:F}'.format(INF), 'INF')
315+
self.assertEqual('{0:f}'.format(-INF), '-inf')
316+
self.assertEqual('{0:F}'.format(-INF), '-INF')
317+
self.assertEqual('{0:f}'.format(NAN), 'nan')
318+
self.assertEqual('{0:F}'.format(NAN), 'NAN')
319+
312320
@unittest.skipUnless(float.__getformat__("double").startswith("IEEE"),
313321
"test requires IEEE 754 doubles")
314322
def test_format_testfile(self):
@@ -321,8 +329,10 @@ def test_format_testfile(self):
321329

322330
lhs, rhs = map(str.strip, line.split('->'))
323331
fmt, arg = lhs.split()
324-
self.assertEqual(fmt % float(arg), rhs)
325-
self.assertEqual(fmt % -float(arg), '-' + rhs)
332+
arg = float(arg)
333+
self.assertEqual(fmt % arg, rhs)
334+
if not math.isnan(arg) and copysign(1.0, arg) > 0.0:
335+
self.assertEqual(fmt % -arg, '-' + rhs)
326336

327337
def test_issue5864(self):
328338
self.assertEquals(format(123.456, '.4'), '123.5')

‎Misc/NEWS‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #3382: 'F' formatting for float and complex now convert the
16+
result to upper case. This only affects 'inf' and 'nan', since 'f'
17+
no longer converts to 'g' for large values.
18+
1519
- Remove switch from "%f" formatting to "%g" formatting for floats
1620
larger than 1e50 in absolute value.
1721

‎Objects/stringlib/formatter.h‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -937,13 +937,6 @@ format_float_internal(PyObject *value,
937937
format the result. We take care of that later. */
938938
type = 'g';
939939

940-
#if PY_VERSION_HEX < 0x0301000
941-
/* 'F' is the same as 'f', per the PEP */
942-
/* This is no longer the case in 3.x */
943-
if (type == 'F')
944-
type = 'f';
945-
#endif
946-
947940
val = PyFloat_AsDouble(value);
948941
if (val == -1.0 && PyErr_Occurred())
949942
goto done;
@@ -1128,13 +1121,6 @@ format_complex_internal(PyObject *value,
11281121
format the result. We take care of that later. */
11291122
type = 'g';
11301123

1131-
#if PY_VERSION_HEX < 0x03010000
1132-
/* This is no longer the case in 3.x */
1133-
/* 'F' is the same as 'f', per the PEP */
1134-
if (type == 'F')
1135-
type = 'f';
1136-
#endif
1137-
11381124
if (precision < 0)
11391125
precision = default_precision;
11401126

‎Objects/stringobject.c‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4966,8 +4966,6 @@ PyString_Format(PyObject *format, PyObject *args)
49664966
case 'F':
49674967
case 'g':
49684968
case 'G':
4969-
if (c == 'F')
4970-
c = 'f';
49714969
temp = formatfloat(v, flags, prec, c);
49724970
if (temp == NULL)
49734971
goto error;

‎Objects/unicodeobject.c‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8809,8 +8809,6 @@ PyObject *PyUnicode_Format(PyObject *format,
88098809
case 'F':
88108810
case 'g':
88118811
case 'G':
8812-
if (c == 'F')
8813-
c = 'f';
88148812
temp = formatfloat(v, flags, prec, c);
88158813
if (temp == NULL)
88168814
goto onError;

0 commit comments

Comments
 (0)