Kaydet (Commit) c04c7c5b authored tarafından Mark Dickinson's avatar Mark Dickinson

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.
üst 8568b198
...@@ -306,7 +306,6 @@ class ComplexTest(unittest.TestCase): ...@@ -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): ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment