mirror of https://github.com/python/cpython
Change int() so that passing a string, unicode, float or long argument
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
This commit is contained in:
parent
7a3bae410d
commit
f171540ab8
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -2516,16 +2516,6 @@ long_coerce(PyObject **pv, PyObject **pw)
|
|||
return 1; /* Can't do it */
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
long_int(PyObject *v)
|
||||
{
|
||||
long x;
|
||||
x = PyLong_AsLong(v);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
return PyInt_FromLong(x);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
long_long(PyObject *v)
|
||||
{
|
||||
|
@ -2533,6 +2523,27 @@ long_long(PyObject *v)
|
|||
return v;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
long_int(PyObject *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 *
|
||||
long_float(PyObject *v)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue