mirror of
https://github.com/python/cpython.git
synced 2025-11-03 11:23:31 +00:00
Issue #7117: Use PyOS_string_to_double instead of PyOS_ascii_strtod in
complexobject.c. Also remove length restriction on unicode inputs to the complex constructor.
This commit is contained in:
parent
8568b19850
commit
c04c7c5b72
3 changed files with 36 additions and 17 deletions
|
|
@ -306,7 +306,6 @@ class ComplexTest(unittest.TestCase):
|
||||||
self.assertRaises(ValueError, complex, "1+(2j)")
|
self.assertRaises(ValueError, complex, "1+(2j)")
|
||||||
self.assertRaises(ValueError, complex, "(1+2j)123")
|
self.assertRaises(ValueError, complex, "(1+2j)123")
|
||||||
if test_support.have_unicode:
|
if test_support.have_unicode:
|
||||||
self.assertRaises(ValueError, complex, unicode("1"*500))
|
|
||||||
self.assertRaises(ValueError, complex, unicode("x"))
|
self.assertRaises(ValueError, complex, unicode("x"))
|
||||||
self.assertRaises(ValueError, complex, "1j+2")
|
self.assertRaises(ValueError, complex, "1j+2")
|
||||||
self.assertRaises(ValueError, complex, "1e1ej")
|
self.assertRaises(ValueError, complex, "1e1ej")
|
||||||
|
|
@ -317,6 +316,10 @@ class ComplexTest(unittest.TestCase):
|
||||||
self.assertRaises(ValueError, complex, "1.11.1j")
|
self.assertRaises(ValueError, complex, "1.11.1j")
|
||||||
self.assertRaises(ValueError, complex, "1e1.1j")
|
self.assertRaises(ValueError, complex, "1e1.1j")
|
||||||
|
|
||||||
|
if test_support.have_unicode:
|
||||||
|
# check that complex accepts long unicode strings
|
||||||
|
self.assertEqual(type(complex(unicode("1"*500))), complex)
|
||||||
|
|
||||||
class EvilExc(Exception):
|
class EvilExc(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Remove length limitation when constructing a complex number from a
|
||||||
|
unicode string.
|
||||||
|
|
||||||
- Removed _PyOS_double_to_string. Use PyOS_double_to_string
|
- Removed _PyOS_double_to_string. Use PyOS_double_to_string
|
||||||
instead. This is in preparation for (but not strictly related to)
|
instead. This is in preparation for (but not strictly related to)
|
||||||
issue #7117, short float repr.
|
issue #7117, short float repr.
|
||||||
|
|
|
||||||
|
|
@ -921,7 +921,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
|
||||||
double x=0.0, y=0.0, z;
|
double x=0.0, y=0.0, z;
|
||||||
int got_bracket=0;
|
int got_bracket=0;
|
||||||
#ifdef Py_USING_UNICODE
|
#ifdef Py_USING_UNICODE
|
||||||
char s_buffer[256];
|
char *s_buffer = NULL;
|
||||||
#endif
|
#endif
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
|
|
||||||
|
|
@ -931,16 +931,14 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
|
||||||
}
|
}
|
||||||
#ifdef Py_USING_UNICODE
|
#ifdef Py_USING_UNICODE
|
||||||
else if (PyUnicode_Check(v)) {
|
else if (PyUnicode_Check(v)) {
|
||||||
if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
|
s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
if (s_buffer == NULL)
|
||||||
"complex() literal too large to convert");
|
return PyErr_NoMemory();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
|
if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
|
||||||
PyUnicode_GET_SIZE(v),
|
PyUnicode_GET_SIZE(v),
|
||||||
s_buffer,
|
s_buffer,
|
||||||
NULL))
|
NULL))
|
||||||
return NULL;
|
goto error;
|
||||||
s = s_buffer;
|
s = s_buffer;
|
||||||
len = strlen(s);
|
len = strlen(s);
|
||||||
}
|
}
|
||||||
|
|
@ -985,21 +983,26 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* first look for forms starting with <float> */
|
/* first look for forms starting with <float> */
|
||||||
errno = 0;
|
z = PyOS_string_to_double(s, &end, NULL);
|
||||||
z = PyOS_ascii_strtod(s, &end);
|
if (z == -1.0 && PyErr_Occurred()) {
|
||||||
if (end == s && errno == ENOMEM)
|
if (PyErr_ExceptionMatches(PyExc_ValueError))
|
||||||
return PyErr_NoMemory();
|
PyErr_Clear();
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (end != s) {
|
if (end != s) {
|
||||||
/* all 4 forms starting with <float> land here */
|
/* all 4 forms starting with <float> land here */
|
||||||
s = end;
|
s = end;
|
||||||
if (*s == '+' || *s == '-') {
|
if (*s == '+' || *s == '-') {
|
||||||
/* <float><signed-float>j | <float><sign>j */
|
/* <float><signed-float>j | <float><sign>j */
|
||||||
x = z;
|
x = z;
|
||||||
errno = 0;
|
y = PyOS_string_to_double(s, &end, NULL);
|
||||||
y = PyOS_ascii_strtod(s, &end);
|
if (y == -1.0 && PyErr_Occurred()) {
|
||||||
if (end == s && errno == ENOMEM)
|
if (PyErr_ExceptionMatches(PyExc_ValueError))
|
||||||
return PyErr_NoMemory();
|
PyErr_Clear();
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (end != s)
|
if (end != s)
|
||||||
/* <float><signed-float>j */
|
/* <float><signed-float>j */
|
||||||
s = end;
|
s = end;
|
||||||
|
|
@ -1053,11 +1056,21 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
|
||||||
if (s-start != len)
|
if (s-start != len)
|
||||||
goto parse_error;
|
goto parse_error;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Py_USING_UNICODE
|
||||||
|
if (s_buffer)
|
||||||
|
PyMem_FREE(s_buffer);
|
||||||
|
#endif
|
||||||
return complex_subtype_from_doubles(type, x, y);
|
return complex_subtype_from_doubles(type, x, y);
|
||||||
|
|
||||||
parse_error:
|
parse_error:
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"complex() arg is a malformed string");
|
"complex() arg is a malformed string");
|
||||||
|
error:
|
||||||
|
#ifdef Py_USING_UNICODE
|
||||||
|
if (s_buffer)
|
||||||
|
PyMem_FREE(s_buffer);
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue