diff Objects/longobject.c @ 37611:7afaa752c772 legacy-trunk

Fix int() and long() to repr() their argument when formatting the exception, to avoid confusing situations like: >>> int("") ValueError: invalid literal for int(): >>> int("2\n\n2") ValueError: invalid literal for int(): 2 2 Also report the base used, to avoid: ValueError: invalid literal for int(): 2 They now report: >>> int("") ValueError: invalid literal for int() with base 10: '' >>> int("2\n\n2") ValueError: invalid literal for int() with base 10: '2\n\n2' >>> int("2", 2) ValueError: invalid literal for int() with base 2: '2' (Reporting the base could be avoided when base is 10, which is the default, but hrm.) Another effect of these changes is that the errormessage can be longer; before, it was cut off at about 250 characters. Now, it can be up to four times as long, as the unrepr'ed string is cut off at 200 characters, instead. No tests were added or changed, since testing for exact errormsgs is (pardon the pun) somewhat errorprone, and I consider not testing the exact text preferable. The actually changed code is tested frequent enough in the test_builtin test as it is (120 runs for each of ints and longs.)
author Thomas Wouters <thomas@python.org>
date Tue, 11 Apr 2006 23:50:33 +0000
parents aeee85b6a5dd
children 20cb13bdf1f0
line wrap: on
line diff
--- a/Objects/longobject.c	Tue Apr 11 21:42:00 2006 +0000
+++ b/Objects/longobject.c	Tue Apr 11 23:50:33 2006 +0000
@@ -1400,6 +1400,8 @@
 	int sign = 1;
 	char *start, *orig_str = str;
 	PyLongObject *z;
+	PyObject *strobj, *strrepr;
+	Py_ssize_t slen;
 
 	if ((base != 0 && base < 2) || base > 36) {
 		PyErr_SetString(PyExc_ValueError,
@@ -1465,9 +1467,19 @@
 	return (PyObject *) z;
 
  onError:
+	Py_XDECREF(z);
+	slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
+	strobj = PyString_FromStringAndSize(orig_str, slen);
+	if (strobj == NULL)
+		return NULL;
+	strrepr = PyObject_Repr(strobj);
+	Py_DECREF(strobj);
+	if (strrepr == NULL)
+		return NULL;
 	PyErr_Format(PyExc_ValueError,
-		     "invalid literal for long(): %.200s", orig_str);
-	Py_XDECREF(z);
+		     "invalid literal for long() with base %d: %s",
+		     base, PyString_AS_STRING(strrepr));
+	Py_DECREF(strrepr);
 	return NULL;
 }