[Python-checkins] r75739 - in python/trunk: Lib/test/test_complex.py Misc/NEWS Objects/complexobject.c

mark.dickinson python-checkins at python.org
Mon Oct 26 23:28:15 CET 2009


Author: mark.dickinson
Date: Mon Oct 26 23:28:14 2009
New Revision: 75739

Log:
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.



Modified:
   python/trunk/Lib/test/test_complex.py
   python/trunk/Misc/NEWS
   python/trunk/Objects/complexobject.c

Modified: python/trunk/Lib/test/test_complex.py
==============================================================================
--- python/trunk/Lib/test/test_complex.py	(original)
+++ python/trunk/Lib/test/test_complex.py	Mon Oct 26 23:28:14 2009
@@ -306,7 +306,6 @@
         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 @@
         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
 

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Mon Oct 26 23:28:14 2009
@@ -12,6 +12,9 @@
 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.

Modified: python/trunk/Objects/complexobject.c
==============================================================================
--- python/trunk/Objects/complexobject.c	(original)
+++ python/trunk/Objects/complexobject.c	Mon Oct 26 23:28:14 2009
@@ -921,7 +921,7 @@
 	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 @@
 	}
 #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 @@
 	*/
 
 	/* 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 @@
 	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;
 }
 


More information about the Python-checkins mailing list