diff -r 787d7587abb5 Lib/test/test_float.py --- a/Lib/test/test_float.py Thu Jan 01 05:04:41 2009 +0100 +++ b/Lib/test/test_float.py Thu Jan 01 16:49:22 2009 +0900 @@ -285,6 +285,14 @@ self.assertEqual(str(float("+infinity")), "inf") self.assertEqual(str(float("-infinity")), "-inf") + for f in ['%f', '%e', '%g']: + self.assertEqual(f % (float("inf")), "inf") + self.assertEqual(f % (float("+inf")), "inf") + self.assertEqual(f % (float("-inf")), "-inf") + self.assertEqual(f % (float("infinity")), "inf") + self.assertEqual(f % (float("+infinity")), "inf") + self.assertEqual(f % (float("-infinity")), "-inf") + self.assertRaises(ValueError, float, "info") self.assertRaises(ValueError, float, "+info") self.assertRaises(ValueError, float, "-info") @@ -319,6 +327,11 @@ self.assertEqual(str(float("nan")), "nan") self.assertEqual(str(float("+nan")), "nan") self.assertEqual(str(float("-nan")), "nan") + + for f in ['%f', '%g', '%e']: + self.assertEqual(f % (float("nan")), "nan") + self.assertEqual(f % (float("+nan")), "nan") + self.assertEqual(f % (float("-nan")), "nan") self.assertRaises(ValueError, float, "nana") self.assertRaises(ValueError, float, "+nana") diff -r 787d7587abb5 Objects/stringobject.c --- a/Objects/stringobject.c Thu Jan 01 05:04:41 2009 +0100 +++ b/Objects/stringobject.c Thu Jan 01 16:49:22 2009 +0900 @@ -4336,6 +4336,9 @@ worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/ char fmt[20]; double x; + register char* cp; + int i; + x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "float argument required, " @@ -4373,6 +4376,47 @@ (flags&F_ALT) ? "#" : "", prec, type); PyOS_ascii_formatd(buf, buflen, fmt, x); + + /* Handle nan and inf */ + cp = buf; + if (*cp == '-') + cp++; + for (; *cp != '\0'; cp++) { + /* Any non-digit means it's not an integer; + this takes care of NAN and INF as well. */ + if (!isdigit(Py_CHARMASK(*cp))) + break; + } + + /* Checking the next three chars should be more than enough to + * detect inf or nan, even on Windows. We check for inf or nan + * at last because they are rare cases. + */ + for (i=0; *cp != '\0' && i<3; cp++, i++) { + if (isdigit(Py_CHARMASK(*cp)) || *cp == '.') + continue; + /* found something that is neither a digit nor point + * it might be a NaN or INF + */ +#ifdef Py_NAN + if (Py_IS_NAN(x)) { + /* we now buf it is a least 4 bytes long because of the + * previous size check a few lines above */ + strcpy(buf, "nan"); + } + else +#endif + if (Py_IS_INFINITY(x)) { + cp = buf; + if (*cp == '-') + cp++; + /* we now buf is a least 5 (sign + 'inf' + '\0') bytes + * long because of the previous size check a few lines + * above*/ + strcpy(cp, "inf"); + } + break; + } return (int)strlen(buf); }