]> granicus.if.org Git - python/commitdiff
Issue #7117: Use PyOS_string_to_double instead of PyOS_ascii_strtod in
authorMark Dickinson <dickinsm@gmail.com>
Mon, 26 Oct 2009 22:28:14 +0000 (22:28 +0000)
committerMark Dickinson <dickinsm@gmail.com>
Mon, 26 Oct 2009 22:28:14 +0000 (22:28 +0000)
complexobject.c.  Also remove length restriction on unicode inputs to
the complex constructor.

Lib/test/test_complex.py
Misc/NEWS
Objects/complexobject.c

index f07a6b4b48e98c73c49273afe4df5a6d91601651..a192ec45ac461413af5591fcaecc9f201453e7ce 100644 (file)
@@ -306,7 +306,6 @@ class ComplexTest(unittest.TestCase):
         self.assertRaises(ValueError, complex, "1+(2j)")
         self.assertRaises(ValueError, complex, "(1+2j)123")
         if test_support.have_unicode:
-            self.assertRaises(ValueError, complex, unicode("1"*500))
             self.assertRaises(ValueError, complex, unicode("x"))
         self.assertRaises(ValueError, complex, "1j+2")
         self.assertRaises(ValueError, complex, "1e1ej")
@@ -317,6 +316,10 @@ class ComplexTest(unittest.TestCase):
         self.assertRaises(ValueError, complex, "1.11.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):
             pass
 
index 368ed3e4af19c38caf917d92ceda9349ff11214f..6d487145ac3b3835c8f7f12ae9122223e19293fd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1
 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
   instead. This is in preparation for (but not strictly related to)
   issue #7117, short float repr.
index b976b6de520dcceb7421be5f39a5a05f51d23538..f277b6625c13a0a0a1d375f4c26743a84992fe74 100644 (file)
@@ -921,7 +921,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
        double x=0.0, y=0.0, z;
        int got_bracket=0;
 #ifdef Py_USING_UNICODE
-       char s_buffer[256];
+       char *s_buffer = NULL;
 #endif
        Py_ssize_t len;
 
@@ -931,16 +931,14 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
        }
 #ifdef Py_USING_UNICODE
        else if (PyUnicode_Check(v)) {
-               if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
-                       PyErr_SetString(PyExc_ValueError,
-                                "complex() literal too large to convert");
-                       return NULL;
-               }
+               s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
+               if (s_buffer == NULL)
+                       return PyErr_NoMemory();
                if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
                                            PyUnicode_GET_SIZE(v),
                                            s_buffer,
                                            NULL))
-                       return NULL;
+                       goto error;
                s = s_buffer;
                len = strlen(s);
        }
@@ -985,21 +983,26 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
        */
 
        /* first look for forms starting with <float> */
-       errno = 0;
-       z = PyOS_ascii_strtod(s, &end);
-       if (end == s && errno == ENOMEM)
-               return PyErr_NoMemory();
-
+       z = PyOS_string_to_double(s, &end, NULL);
+       if (z == -1.0 && PyErr_Occurred()) {
+               if (PyErr_ExceptionMatches(PyExc_ValueError))
+                       PyErr_Clear();
+               else
+                       goto error;
+       }
        if (end != s) {
                /* all 4 forms starting with <float> land here */
                s = end;
                if (*s == '+' || *s == '-') {
                        /* <float><signed-float>j | <float><sign>j */
                        x = z;
-                       errno = 0;
-                       y = PyOS_ascii_strtod(s, &end);
-                       if (end == s && errno == ENOMEM)
-                               return PyErr_NoMemory();
+                       y = PyOS_string_to_double(s, &end, NULL);
+                       if (y == -1.0 && PyErr_Occurred()) {
+                               if (PyErr_ExceptionMatches(PyExc_ValueError))
+                                       PyErr_Clear();
+                               else
+                                       goto error;
+                       }
                        if (end != s)
                                /* <float><signed-float>j */
                                s = end;
@@ -1053,11 +1056,21 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
        if (s-start != len)
                goto parse_error;
 
+
+#ifdef Py_USING_UNICODE
+       if (s_buffer)
+               PyMem_FREE(s_buffer);
+#endif
        return complex_subtype_from_doubles(type, x, y);
 
   parse_error:
        PyErr_SetString(PyExc_ValueError,
                        "complex() arg is a malformed string");
+  error:
+#ifdef Py_USING_UNICODE
+       if (s_buffer)
+               PyMem_FREE(s_buffer);
+#endif
        return NULL;
 }