Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e7214a1

Browse files
committed
Get float() to be more portable across platforms. Disable hex strings.
1 parent 87b801c commit e7214a1

3 files changed

Lines changed: 32 additions & 50 deletions

File tree

Lib/test/test_builtin.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@ def test_float(self):
545545
self.assertEqual(float(314), 314.0)
546546
self.assertEqual(float(314L), 314.0)
547547
self.assertEqual(float(" 3.14 "), 3.14)
548+
self.assertRaises(ValueError, float, " 0x3.1 ")
549+
self.assertRaises(ValueError, float, " -0x3.p-1 ")
548550
if have_unicode:
549551
self.assertEqual(float(unicode(" 3.14 ")), 3.14)
550552
self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14)
@@ -572,8 +574,8 @@ def test_float_with_comma(self):
572574
self.assertEqual(float(" 3,14 "), 3.14)
573575
self.assertEqual(float(" +3,14 "), 3.14)
574576
self.assertEqual(float(" -3,14 "), -3.14)
575-
self.assertEqual(float(" 0x3.1 "), 3.0625)
576-
self.assertEqual(float(" -0x3.p-1 "), -1.5)
577+
self.assertRaises(ValueError, float, " 0x3.1 ")
578+
self.assertRaises(ValueError, float, " -0x3.p-1 ")
577579
self.assertEqual(float(" 25.e-1 "), 2.5)
578580
self.assertEqual(fcmp(float(" .25e-1 "), .025), 0)
579581
finally:

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1?
1212
Core and builtins
1313
-----------------
1414

15+
- Support for converting hex strings to floats no longer works.
16+
This was not portable. float('0x3') now raises a ValueError.
17+
1518
- Patch #1382163: Expose Subversion revision number to Python. New C API
1619
function Py_GetBuildNumber(). New attribute sys.build_number. Build number
1720
is now displayed in interactive prompt banner.

Python/pystrtod.c

Lines changed: 25 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838
* Return value: the #gdouble value.
3939
**/
4040
double
41-
PyOS_ascii_strtod(const char *nptr,
42-
char **endptr)
41+
PyOS_ascii_strtod(const char *nptr, char **endptr)
4342
{
4443
char *fail_pos;
4544
double val;
@@ -49,7 +48,6 @@ PyOS_ascii_strtod(const char *nptr,
4948
const char *p, *decimal_point_pos;
5049
const char *end = NULL; /* Silence gcc */
5150

52-
/* g_return_val_if_fail (nptr != NULL, 0); */
5351
assert(nptr != NULL);
5452

5553
fail_pos = NULL;
@@ -73,64 +71,36 @@ PyOS_ascii_strtod(const char *nptr,
7371
if (*p == '+' || *p == '-')
7472
p++;
7573

76-
if (p[0] == '0' &&
77-
(p[1] == 'x' || p[1] == 'X'))
74+
while (ISDIGIT(*p))
75+
p++;
76+
77+
if (*p == '.')
7878
{
79-
p += 2;
80-
/* HEX - find the (optional) decimal point */
79+
decimal_point_pos = p++;
8180

82-
while (ISXDIGIT(*p))
81+
while (ISDIGIT(*p))
8382
p++;
8483

85-
if (*p == '.')
86-
{
87-
decimal_point_pos = p++;
88-
89-
while (ISXDIGIT(*p))
90-
p++;
91-
92-
if (*p == 'p' || *p == 'P')
93-
p++;
94-
if (*p == '+' || *p == '-')
95-
p++;
96-
while (ISDIGIT(*p))
97-
p++;
98-
end = p;
99-
}
100-
}
101-
else
102-
{
84+
if (*p == 'e' || *p == 'E')
85+
p++;
86+
if (*p == '+' || *p == '-')
87+
p++;
10388
while (ISDIGIT(*p))
10489
p++;
105-
106-
if (*p == '.')
107-
{
108-
decimal_point_pos = p++;
109-
110-
while (ISDIGIT(*p))
111-
p++;
112-
113-
if (*p == 'e' || *p == 'E')
114-
p++;
115-
if (*p == '+' || *p == '-')
116-
p++;
117-
while (ISDIGIT(*p))
118-
p++;
119-
end = p;
120-
}
90+
end = p;
12191
}
122-
/* For the other cases, we need not convert the decimal point */
92+
/* For the other cases, we need not convert the decimal point */
12393
}
12494

125-
/* Set errno to zero, so that we can distinguish zero results
126-
and underflows */
95+
/* Set errno to zero, so that we can distinguish zero results
96+
and underflows */
12797
errno = 0;
12898

12999
if (decimal_point_pos)
130100
{
131101
char *copy, *c;
132102

133-
/* We need to convert the '.' to the locale specific decimal point */
103+
/* We need to convert the '.' to the locale specific decimal point */
134104
copy = malloc(end - nptr + 1 + decimal_point_len);
135105

136106
c = copy;
@@ -155,8 +125,15 @@ PyOS_ascii_strtod(const char *nptr,
155125
free(copy);
156126

157127
}
158-
else
159-
val = strtod(nptr, &fail_pos);
128+
else {
129+
unsigned i = 0;
130+
if (nptr[i] == '-')
131+
i++;
132+
if (nptr[i] == '0' && (nptr[i+1] == 'x' || nptr[i+1] == 'X'))
133+
fail_pos = nptr;
134+
else
135+
val = strtod(nptr, &fail_pos);
136+
}
160137

161138
if (endptr)
162139
*endptr = fail_pos;

0 commit comments

Comments
 (0)