]> granicus.if.org Git - python/commitdiff
Change int() so that passing a string, unicode, float or long argument
authorWalter Dörwald <walter@livinglogic.de>
Tue, 19 Nov 2002 20:49:15 +0000 (20:49 +0000)
committerWalter Dörwald <walter@livinglogic.de>
Tue, 19 Nov 2002 20:49:15 +0000 (20:49 +0000)
that is outside the integer range no longer raises OverflowError, but
returns a long object instead.

This fixes SF bug http://www.python.org/sf/635115

Doc/api/abstract.tex
Doc/lib/libfuncs.tex
Lib/test/test_b1.py
Lib/test/test_long.py
Lib/test/test_types.py
Misc/NEWS
Objects/floatobject.c
Objects/intobject.c
Objects/longobject.c

index 6bf96b235226af9023daf45d505ab73322a8164b..c5939b2b2f35ff0348df5385804be66b705f2418 100644 (file)
@@ -650,8 +650,9 @@ determination.
 
 \begin{cfuncdesc}{PyObject*}{PyNumber_Int}{PyObject *o}
   Returns the \var{o} converted to an integer object on success, or
-  \NULL{} on failure.  This is the equivalent of the Python expression
-  \samp{int(\var{o})}.\bifuncindex{int}
+  \NULL{} on failure.  If the argument is outside the integer range
+  a long object will be returned instead. This is the equivalent
+  of the Python expression \samp{int(\var{o})}.\bifuncindex{int}
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyNumber_Long}{PyObject *o}
index f6b01d1211cfdcb0ead814eabef0af2ed2a3bab9..9fab9ba22c5f1d0f2a63a8d6f04018e3a99852de 100644 (file)
@@ -507,6 +507,8 @@ def my_import(name):
   Otherwise, the argument may be a plain or
   long integer or a floating point number.  Conversion of floating
   point numbers to integers truncates (towards zero).
+  If the argument is outside the integer range a long object will
+  be returned instead.
 \end{funcdesc}
 
 \begin{funcdesc}{intern}{string}
index 249f1fa76fbf3b0bbb6109d70bd12fb178c5dd8f..3033667d96ce8064c187d6879a8e559c34e016fc 100644 (file)
@@ -438,17 +438,19 @@ try:
 except:
     raise TestFailed, "int(%s)" % `s[1:]` + " should return long"
 try:
-    int(1e100)
+    x = int(1e100)
 except OverflowError:
-    pass
+    raise TestFailed("int(1e100) mustn't raise OverflowError")
 else:
-    raise TestFailed("int(1e100) expected OverflowError")
+    if not isinstance(x, long):
+        raise TestFailed("int(1e100) should have returned long")
 try:
-    int(-1e100)
+    x = int(-1e100)
 except OverflowError:
-    pass
+    raise TestFailed("int(-1e100) mustn't raise OverflowError")
 else:
-    raise TestFailed("int(-1e100) expected OverflowError")
+    if not isinstance(x, long):
+        raise TestFailed("int(-1e100) should have returned long")
 
 
 # SF bug 434186:  0x80000000/2 != 0x80000000>>1.
index 93197346016ce882b94c9d00b605eb6f243f564f..9cab2dec792f59be7a80ace23960577c9cfd3fea 100644 (file)
@@ -267,22 +267,26 @@ def test_misc(maxdigits=MAXDIGITS):
     # but long -> int should overflow for hugepos+1 and hugeneg-1
     x = hugepos_aslong + 1
     try:
-        int(x)
-        raise ValueError
+        y = int(x)
     except OverflowError:
-        pass
-    except:
-        raise TestFailed, "int(long(sys.maxint) + 1) didn't overflow"
+        raise TestFailed, "int(long(sys.maxint) + 1) mustn't overflow"
+    if not isinstance(y, long):
+        raise TestFailed("int(long(sys.maxint) + 1) should have returned long")
 
     x = hugeneg_aslong - 1
     try:
-        int(x)
-        raise ValueError
+        y = int(x)
     except OverflowError:
-        pass
-    except:
-        raise TestFailed, "int(long(-sys.maxint-1) - 1) didn't overflow"
+        raise TestFailed, "int(long(-sys.maxint-1) - 1) mustn't overflow"
+    if not isinstance(y, long):
+        raise TestFailed("int(long(-sys.maxint-1) - 1) should have returned long")
 
+    class long2(long):
+        pass
+    x = long2(1L<<100)
+    y = int(x)
+    if type(y) is not long:
+        raise TestFailed("overflowing int conversion must return long not long subtype")
 # ----------------------------------- tests of auto int->long conversion
 
 def test_auto_overflow():
index d075d9470de55115aaa86f9c5d93ac1240c63f52..c20af2e6f383cbee0812dd1c98c7c57fa9570b54 100644 (file)
@@ -138,16 +138,16 @@ if not 12L < 24L: raise TestFailed, 'long op'
 if not -24L < -12L: raise TestFailed, 'long op'
 x = sys.maxint
 if int(long(x)) != x: raise TestFailed, 'long op'
-try: int(long(x)+1L)
-except OverflowError: pass
-else:raise TestFailed, 'long op'
+try: y = int(long(x)+1L)
+except OverflowError: raise TestFailed, 'long op'
+if not isinstance(y, long): raise TestFailed, 'long op'
 x = -x
 if int(long(x)) != x: raise TestFailed, 'long op'
 x = x-1
 if int(long(x)) != x: raise TestFailed, 'long op'
-try: int(long(x)-1L)
-except OverflowError: pass
-else:raise TestFailed, 'long op'
+try: y = int(long(x)-1L)
+except OverflowError: raise TestFailed, 'long op'
+if not isinstance(y, long): raise TestFailed, 'long op'
 
 try: 5 << -5
 except ValueError: pass
index 3129276d9cba8773f97b407a2172c7d448cc4a61..73ee64a5785c39d65935d342d6da9874afff5ea0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -11,6 +11,9 @@ What's New in Python 2.3 alpha 1?
 
 Type/class unification and new-style classes
 --------------------------------------------
+- int() now returns a long object if the argument is outside the
+  integer range, so int("4"*1000), int(1e200) and int(1L<<1000) will
+  all return long objects instead of raising an OverflowError.
 
 - Assignment to __class__ is disallowed if either the old or the new
   class is a statically allocated type object (such as defined by an
index 924b31293b0f259720899cf49331fa6b16ca8625..129f5bdc5f89e69e90c85e8f481e8d26a2bdebf4 100644 (file)
@@ -641,6 +641,13 @@ float_coerce(PyObject **pv, PyObject **pw)
        return 1; /* Can't do it */
 }
 
+static PyObject *
+float_long(PyObject *v)
+{
+       double x = PyFloat_AsDouble(v);
+       return PyLong_FromDouble(x);
+}
+
 static PyObject *
 float_int(PyObject *v)
 {
@@ -652,8 +659,7 @@ float_int(PyObject *v)
 #ifdef RISCOS
        /* conversion from floating to integral type would raise exception */
        if (wholepart>LONG_MAX || wholepart<LONG_MIN) {
-               PyErr_SetString(PyExc_OverflowError, "float too large to convert");
-               return NULL;
+               return float_long(v);
        }
 #endif
        /* doubles may have more bits than longs, or vice versa; and casting
@@ -663,15 +669,7 @@ float_int(PyObject *v)
        aslong = (long)wholepart;
        if ((double)aslong == wholepart)
                return PyInt_FromLong(aslong);
-       PyErr_SetString(PyExc_OverflowError, "float too large to convert");
-       return NULL;
-}
-
-static PyObject *
-float_long(PyObject *v)
-{
-       double x = PyFloat_AsDouble(v);
-       return PyLong_FromDouble(x);
+       return float_long(v);
 }
 
 static PyObject *
index e33908591cf945322a6b6d798d4d1aeffe98ce77..7242dd017061c8fecada3d41259c320a2d6bc37d 100644 (file)
@@ -166,9 +166,20 @@ PyInt_AsLong(register PyObject *op)
        if (io == NULL)
                return -1;
        if (!PyInt_Check(io)) {
-               PyErr_SetString(PyExc_TypeError,
-                               "nb_int should return int object");
-               return -1;
+               if (PyLong_Check(io)) {
+                       /* got a long? => retry int conversion */
+                       val = PyLong_AsLong((PyObject *)io);
+                       if (PyErr_Occurred()) {
+                               Py_DECREF(io);
+                               return -1;
+                       }
+               }
+               else
+               {
+                       PyErr_SetString(PyExc_TypeError,
+                                       "nb_int should return int object");
+                       return -1;
+               }
        }
 
        val = PyInt_AS_LONG(io);
@@ -892,7 +903,8 @@ Convert a string or number to an integer, if possible.  A floating point\n\
 argument will be truncated towards zero (this does not include a string\n\
 representation of a floating point number!)  When converting a string, use\n\
 the optional base.  It is an error to supply a base when converting a\n\
-non-string.");
+non-string. If the argument is outside the integer range a long object\n\
+will be returned instead.");
 
 static PyNumberMethods int_as_number = {
        (binaryfunc)int_add,    /*nb_add*/
index 7374fce9dd9242b27d2ed32d11d816ac2db373ff..5038823334b65b448fc7fa2a2e81dce06e8b0e45 100644 (file)
@@ -2517,20 +2517,31 @@ long_coerce(PyObject **pv, PyObject **pw)
 }
 
 static PyObject *
-long_int(PyObject *v)
+long_long(PyObject *v)
 {
-       long x;
-       x = PyLong_AsLong(v);
-       if (PyErr_Occurred())
-               return NULL;
-       return PyInt_FromLong(x);
+       Py_INCREF(v);
+       return v;
 }
 
 static PyObject *
-long_long(PyObject *v)
+long_int(PyObject *v)
 {
-       Py_INCREF(v);
-       return v;
+       long x;
+       x = PyLong_AsLong(v);
+       if (PyErr_Occurred()) {
+               if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+                               PyErr_Clear();
+                               if (PyLong_CheckExact(v)) {
+                                       Py_INCREF(v);
+                                       return v;
+                               }
+                               else
+                                       return _PyLong_Copy((PyLongObject *)v);
+               }
+               else
+                       return NULL;
+       }
+       return PyInt_FromLong(x);
 }
 
 static PyObject *