Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f171540

Browse files
committed
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
1 parent 7a3bae4 commit f171540

9 files changed

Lines changed: 81 additions & 48 deletions

File tree

Doc/api/abstract.tex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,9 @@ \section{Number Protocol \label{number}}
650650

651651
\begin{cfuncdesc}{PyObject*}{PyNumber_Int}{PyObject *o}
652652
Returns the \var{o} converted to an integer object on success, or
653-
\NULL{} on failure. This is the equivalent of the Python expression
654-
\samp{int(\var{o})}.\bifuncindex{int}
653+
\NULL{} on failure. If the argument is outside the integer range
654+
a long object will be returned instead. This is the equivalent
655+
of the Python expression \samp{int(\var{o})}.\bifuncindex{int}
655656
\end{cfuncdesc}
656657

657658
\begin{cfuncdesc}{PyObject*}{PyNumber_Long}{PyObject *o}

Doc/lib/libfuncs.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,8 @@ \section{Built-in Functions \label{built-in-funcs}}
507507
Otherwise, the argument may be a plain or
508508
long integer or a floating point number. Conversion of floating
509509
point numbers to integers truncates (towards zero).
510+
If the argument is outside the integer range a long object will
511+
be returned instead.
510512
\end{funcdesc}
511513

512514
\begin{funcdesc}{intern}{string}

Lib/test/test_b1.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,17 +438,19 @@ def f(): pass
438438
except:
439439
raise TestFailed, "int(%s)" % `s[1:]` + " should return long"
440440
try:
441-
int(1e100)
441+
x = int(1e100)
442442
except OverflowError:
443-
pass
443+
raise TestFailed("int(1e100) mustn't raise OverflowError")
444444
else:
445-
raise TestFailed("int(1e100) expected OverflowError")
445+
if not isinstance(x, long):
446+
raise TestFailed("int(1e100) should have returned long")
446447
try:
447-
int(-1e100)
448+
x = int(-1e100)
448449
except OverflowError:
449-
pass
450+
raise TestFailed("int(-1e100) mustn't raise OverflowError")
450451
else:
451-
raise TestFailed("int(-1e100) expected OverflowError")
452+
if not isinstance(x, long):
453+
raise TestFailed("int(-1e100) should have returned long")
452454

453455

454456
# SF bug 434186: 0x80000000/2 != 0x80000000>>1.

Lib/test/test_long.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -267,22 +267,26 @@ def test_misc(maxdigits=MAXDIGITS):
267267
# but long -> int should overflow for hugepos+1 and hugeneg-1
268268
x = hugepos_aslong + 1
269269
try:
270-
int(x)
271-
raise ValueError
270+
y = int(x)
272271
except OverflowError:
273-
pass
274-
except:
275-
raise TestFailed, "int(long(sys.maxint) + 1) didn't overflow"
272+
raise TestFailed, "int(long(sys.maxint) + 1) mustn't overflow"
273+
if not isinstance(y, long):
274+
raise TestFailed("int(long(sys.maxint) + 1) should have returned long")
276275

277276
x = hugeneg_aslong - 1
278277
try:
279-
int(x)
280-
raise ValueError
278+
y = int(x)
281279
except OverflowError:
282-
pass
283-
except:
284-
raise TestFailed, "int(long(-sys.maxint-1) - 1) didn't overflow"
280+
raise TestFailed, "int(long(-sys.maxint-1) - 1) mustn't overflow"
281+
if not isinstance(y, long):
282+
raise TestFailed("int(long(-sys.maxint-1) - 1) should have returned long")
285283

284+
class long2(long):
285+
pass
286+
x = long2(1L<<100)
287+
y = int(x)
288+
if type(y) is not long:
289+
raise TestFailed("overflowing int conversion must return long not long subtype")
286290
# ----------------------------------- tests of auto int->long conversion
287291

288292
def test_auto_overflow():

Lib/test/test_types.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,16 @@ class C: pass
138138
if not -24L < -12L: raise TestFailed, 'long op'
139139
x = sys.maxint
140140
if int(long(x)) != x: raise TestFailed, 'long op'
141-
try: int(long(x)+1L)
142-
except OverflowError: pass
143-
else:raise TestFailed, 'long op'
141+
try: y = int(long(x)+1L)
142+
except OverflowError: raise TestFailed, 'long op'
143+
if not isinstance(y, long): raise TestFailed, 'long op'
144144
x = -x
145145
if int(long(x)) != x: raise TestFailed, 'long op'
146146
x = x-1
147147
if int(long(x)) != x: raise TestFailed, 'long op'
148-
try: int(long(x)-1L)
149-
except OverflowError: pass
150-
else:raise TestFailed, 'long op'
148+
try: y = int(long(x)-1L)
149+
except OverflowError: raise TestFailed, 'long op'
150+
if not isinstance(y, long): raise TestFailed, 'long op'
151151

152152
try: 5 << -5
153153
except ValueError: pass

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ What's New in Python 2.3 alpha 1?
1111

1212
Type/class unification and new-style classes
1313
--------------------------------------------
14+
- int() now returns a long object if the argument is outside the
15+
integer range, so int("4"*1000), int(1e200) and int(1L<<1000) will
16+
all return long objects instead of raising an OverflowError.
1417

1518
- Assignment to __class__ is disallowed if either the old or the new
1619
class is a statically allocated type object (such as defined by an

Objects/floatobject.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,13 @@ float_coerce(PyObject **pv, PyObject **pw)
641641
return 1; /* Can't do it */
642642
}
643643

644+
static PyObject *
645+
float_long(PyObject *v)
646+
{
647+
double x = PyFloat_AsDouble(v);
648+
return PyLong_FromDouble(x);
649+
}
650+
644651
static PyObject *
645652
float_int(PyObject *v)
646653
{
@@ -652,8 +659,7 @@ float_int(PyObject *v)
652659
#ifdef RISCOS
653660
/* conversion from floating to integral type would raise exception */
654661
if (wholepart>LONG_MAX || wholepart<LONG_MIN) {
655-
PyErr_SetString(PyExc_OverflowError, "float too large to convert");
656-
return NULL;
662+
return float_long(v);
657663
}
658664
#endif
659665
/* doubles may have more bits than longs, or vice versa; and casting
@@ -663,15 +669,7 @@ float_int(PyObject *v)
663669
aslong = (long)wholepart;
664670
if ((double)aslong == wholepart)
665671
return PyInt_FromLong(aslong);
666-
PyErr_SetString(PyExc_OverflowError, "float too large to convert");
667-
return NULL;
668-
}
669-
670-
static PyObject *
671-
float_long(PyObject *v)
672-
{
673-
double x = PyFloat_AsDouble(v);
674-
return PyLong_FromDouble(x);
672+
return float_long(v);
675673
}
676674

677675
static PyObject *

Objects/intobject.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,20 @@ PyInt_AsLong(register PyObject *op)
166166
if (io == NULL)
167167
return -1;
168168
if (!PyInt_Check(io)) {
169-
PyErr_SetString(PyExc_TypeError,
170-
"nb_int should return int object");
171-
return -1;
169+
if (PyLong_Check(io)) {
170+
/* got a long? => retry int conversion */
171+
val = PyLong_AsLong((PyObject *)io);
172+
if (PyErr_Occurred()) {
173+
Py_DECREF(io);
174+
return -1;
175+
}
176+
}
177+
else
178+
{
179+
PyErr_SetString(PyExc_TypeError,
180+
"nb_int should return int object");
181+
return -1;
182+
}
172183
}
173184

174185
val = PyInt_AS_LONG(io);
@@ -892,7 +903,8 @@ Convert a string or number to an integer, if possible. A floating point\n\
892903
argument will be truncated towards zero (this does not include a string\n\
893904
representation of a floating point number!) When converting a string, use\n\
894905
the optional base. It is an error to supply a base when converting a\n\
895-
non-string.");
906+
non-string. If the argument is outside the integer range a long object\n\
907+
will be returned instead.");
896908

897909
static PyNumberMethods int_as_number = {
898910
(binaryfunc)int_add, /*nb_add*/

Objects/longobject.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,20 +2517,31 @@ long_coerce(PyObject **pv, PyObject **pw)
25172517
}
25182518

25192519
static PyObject *
2520-
long_int(PyObject *v)
2520+
long_long(PyObject *v)
25212521
{
2522-
long x;
2523-
x = PyLong_AsLong(v);
2524-
if (PyErr_Occurred())
2525-
return NULL;
2526-
return PyInt_FromLong(x);
2522+
Py_INCREF(v);
2523+
return v;
25272524
}
25282525

25292526
static PyObject *
2530-
long_long(PyObject *v)
2527+
long_int(PyObject *v)
25312528
{
2532-
Py_INCREF(v);
2533-
return v;
2529+
long x;
2530+
x = PyLong_AsLong(v);
2531+
if (PyErr_Occurred()) {
2532+
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
2533+
PyErr_Clear();
2534+
if (PyLong_CheckExact(v)) {
2535+
Py_INCREF(v);
2536+
return v;
2537+
}
2538+
else
2539+
return _PyLong_Copy((PyLongObject *)v);
2540+
}
2541+
else
2542+
return NULL;
2543+
}
2544+
return PyInt_FromLong(x);
25342545
}
25352546

25362547
static PyObject *

0 commit comments

Comments
 (0)