diff options
-rw-r--r-- | Lib/test/test_builtin.py | 6 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Python/pystrtod.c | 73 |
3 files changed, 32 insertions, 50 deletions
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index c8a4822..6248972 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -545,6 +545,8 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(float(314), 314.0) self.assertEqual(float(314L), 314.0) self.assertEqual(float(" 3.14 "), 3.14) + self.assertRaises(ValueError, float, " 0x3.1 ") + self.assertRaises(ValueError, float, " -0x3.p-1 ") if have_unicode: self.assertEqual(float(unicode(" 3.14 ")), 3.14) self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14) @@ -572,8 +574,8 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(float(" 3,14 "), 3.14) self.assertEqual(float(" +3,14 "), 3.14) self.assertEqual(float(" -3,14 "), -3.14) - self.assertEqual(float(" 0x3.1 "), 3.0625) - self.assertEqual(float(" -0x3.p-1 "), -1.5) + self.assertRaises(ValueError, float, " 0x3.1 ") + self.assertRaises(ValueError, float, " -0x3.p-1 ") self.assertEqual(float(" 25.e-1 "), 2.5) self.assertEqual(fcmp(float(" .25e-1 "), .025), 0) finally: @@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1? Core and builtins ----------------- +- Support for converting hex strings to floats no longer works. + This was not portable. float('0x3') now raises a ValueError. + - Patch #1382163: Expose Subversion revision number to Python. New C API function Py_GetBuildNumber(). New attribute sys.build_number. Build number is now displayed in interactive prompt banner. diff --git a/Python/pystrtod.c b/Python/pystrtod.c index ab25799..19f25da 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -38,8 +38,7 @@ * Return value: the #gdouble value. **/ double -PyOS_ascii_strtod(const char *nptr, - char **endptr) +PyOS_ascii_strtod(const char *nptr, char **endptr) { char *fail_pos; double val; @@ -49,7 +48,6 @@ PyOS_ascii_strtod(const char *nptr, const char *p, *decimal_point_pos; const char *end = NULL; /* Silence gcc */ -/* g_return_val_if_fail (nptr != NULL, 0); */ assert(nptr != NULL); fail_pos = NULL; @@ -73,64 +71,36 @@ PyOS_ascii_strtod(const char *nptr, if (*p == '+' || *p == '-') p++; - if (p[0] == '0' && - (p[1] == 'x' || p[1] == 'X')) + while (ISDIGIT(*p)) + p++; + + if (*p == '.') { - p += 2; - /* HEX - find the (optional) decimal point */ + decimal_point_pos = p++; - while (ISXDIGIT(*p)) + while (ISDIGIT(*p)) p++; - if (*p == '.') - { - decimal_point_pos = p++; - - while (ISXDIGIT(*p)) - p++; - - if (*p == 'p' || *p == 'P') - p++; - if (*p == '+' || *p == '-') - p++; - while (ISDIGIT(*p)) - p++; - end = p; - } - } - else - { + if (*p == 'e' || *p == 'E') + p++; + if (*p == '+' || *p == '-') + p++; while (ISDIGIT(*p)) p++; - - if (*p == '.') - { - decimal_point_pos = p++; - - while (ISDIGIT(*p)) - p++; - - if (*p == 'e' || *p == 'E') - p++; - if (*p == '+' || *p == '-') - p++; - while (ISDIGIT(*p)) - p++; - end = p; - } + end = p; } - /* For the other cases, we need not convert the decimal point */ + /* For the other cases, we need not convert the decimal point */ } - /* Set errno to zero, so that we can distinguish zero results - and underflows */ + /* Set errno to zero, so that we can distinguish zero results + and underflows */ errno = 0; if (decimal_point_pos) { char *copy, *c; - /* We need to convert the '.' to the locale specific decimal point */ + /* We need to convert the '.' to the locale specific decimal point */ copy = malloc(end - nptr + 1 + decimal_point_len); c = copy; @@ -155,8 +125,15 @@ PyOS_ascii_strtod(const char *nptr, free(copy); } - else - val = strtod(nptr, &fail_pos); + else { + unsigned i = 0; + if (nptr[i] == '-') + i++; + if (nptr[i] == '0' && (nptr[i+1] == 'x' || nptr[i+1] == 'X')) + fail_pos = nptr; + else + val = strtod(nptr, &fail_pos); + } if (endptr) *endptr = fail_pos; |