Skip to content

Commit dba44f0

Browse files
bpo-37999: No longer use __int__ in implicit integer conversions.
Only __index__ should be used to make integer conversions lossless.
1 parent 41c57b3 commit dba44f0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+189
-2600
lines changed

Doc/whatsnew/3.9.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ Other Language Changes
9999
ignored for empty strings.
100100
(Contributed by Victor Stinner in :issue:`37388`.)
101101

102+
* Builtin and extension functions that take integer arguments no longer accept
103+
:class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ s and other
104+
objects that can be converted to integers only with a loss (e.g. that have
105+
the :meth:`~object.__int__` method but do not have the
106+
:meth:`~object.__index__` method).
107+
(Contributed by Serhiy Storchaka in :issue:`37999`.)
108+
102109

103110
New Modules
104111
===========

Include/longobject.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -173,23 +173,6 @@ PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
173173
unsigned char* bytes, size_t n,
174174
int little_endian, int is_signed);
175175

176-
/* _PyLong_FromNbInt: Convert the given object to a PyLongObject
177-
using the nb_int slot, if available. Raise TypeError if either the
178-
nb_int slot is not available or the result of the call to nb_int
179-
returns something not of type int.
180-
*/
181-
PyAPI_FUNC(PyObject *) _PyLong_FromNbInt(PyObject *);
182-
183-
/* Convert the given object to a PyLongObject using the nb_index or
184-
nb_int slots, if available (the latter is deprecated).
185-
Raise TypeError if either nb_index and nb_int slots are not
186-
available or the result of the call to nb_index or nb_int
187-
returns something not of type int.
188-
Should be replaced with PyNumber_Index after the end of the
189-
deprecation period.
190-
*/
191-
PyAPI_FUNC(PyObject *) _PyLong_FromNbIndexOrNbInt(PyObject *);
192-
193176
/* _PyLong_Format: Convert the long to a string object with given base,
194177
appending a base prefix of 0[box] if base is 2, 8 or 16. */
195178
PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Builtin and extension functions that take integer arguments no longer accept
2+
:class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ s and other
3+
objects that can be converted to integers only with a loss (e.g. that have
4+
the :meth:`~object.__int__` method but do not have the
5+
:meth:`~object.__index__` method).

Modules/_blake2/clinic/blake2b_impl.c.h

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5454
goto skip_optional_kwonly;
5555
}
5656
if (fastargs[1]) {
57-
if (PyFloat_Check(fastargs[1])) {
58-
PyErr_SetString(PyExc_TypeError,
59-
"integer argument expected, got float" );
60-
goto exit;
61-
}
6257
digest_size = _PyLong_AsInt(fastargs[1]);
6358
if (digest_size == -1 && PyErr_Occurred()) {
6459
goto exit;
@@ -104,11 +99,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
10499
}
105100
}
106101
if (fastargs[5]) {
107-
if (PyFloat_Check(fastargs[5])) {
108-
PyErr_SetString(PyExc_TypeError,
109-
"integer argument expected, got float" );
110-
goto exit;
111-
}
112102
fanout = _PyLong_AsInt(fastargs[5]);
113103
if (fanout == -1 && PyErr_Occurred()) {
114104
goto exit;
@@ -118,11 +108,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
118108
}
119109
}
120110
if (fastargs[6]) {
121-
if (PyFloat_Check(fastargs[6])) {
122-
PyErr_SetString(PyExc_TypeError,
123-
"integer argument expected, got float" );
124-
goto exit;
125-
}
126111
depth = _PyLong_AsInt(fastargs[6]);
127112
if (depth == -1 && PyErr_Occurred()) {
128113
goto exit;
@@ -148,11 +133,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
148133
}
149134
}
150135
if (fastargs[9]) {
151-
if (PyFloat_Check(fastargs[9])) {
152-
PyErr_SetString(PyExc_TypeError,
153-
"integer argument expected, got float" );
154-
goto exit;
155-
}
156136
node_depth = _PyLong_AsInt(fastargs[9]);
157137
if (node_depth == -1 && PyErr_Occurred()) {
158138
goto exit;
@@ -162,11 +142,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
162142
}
163143
}
164144
if (fastargs[10]) {
165-
if (PyFloat_Check(fastargs[10])) {
166-
PyErr_SetString(PyExc_TypeError,
167-
"integer argument expected, got float" );
168-
goto exit;
169-
}
170145
inner_size = _PyLong_AsInt(fastargs[10]);
171146
if (inner_size == -1 && PyErr_Occurred()) {
172147
goto exit;
@@ -261,4 +236,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored))
261236
{
262237
return _blake2_blake2b_hexdigest_impl(self);
263238
}
264-
/*[clinic end generated code: output=cbb625d7f60c288c input=a9049054013a1b77]*/
239+
/*[clinic end generated code: output=f6102672dca4278a input=a9049054013a1b77]*/

Modules/_blake2/clinic/blake2s_impl.c.h

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5454
goto skip_optional_kwonly;
5555
}
5656
if (fastargs[1]) {
57-
if (PyFloat_Check(fastargs[1])) {
58-
PyErr_SetString(PyExc_TypeError,
59-
"integer argument expected, got float" );
60-
goto exit;
61-
}
6257
digest_size = _PyLong_AsInt(fastargs[1]);
6358
if (digest_size == -1 && PyErr_Occurred()) {
6459
goto exit;
@@ -104,11 +99,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
10499
}
105100
}
106101
if (fastargs[5]) {
107-
if (PyFloat_Check(fastargs[5])) {
108-
PyErr_SetString(PyExc_TypeError,
109-
"integer argument expected, got float" );
110-
goto exit;
111-
}
112102
fanout = _PyLong_AsInt(fastargs[5]);
113103
if (fanout == -1 && PyErr_Occurred()) {
114104
goto exit;
@@ -118,11 +108,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
118108
}
119109
}
120110
if (fastargs[6]) {
121-
if (PyFloat_Check(fastargs[6])) {
122-
PyErr_SetString(PyExc_TypeError,
123-
"integer argument expected, got float" );
124-
goto exit;
125-
}
126111
depth = _PyLong_AsInt(fastargs[6]);
127112
if (depth == -1 && PyErr_Occurred()) {
128113
goto exit;
@@ -148,11 +133,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
148133
}
149134
}
150135
if (fastargs[9]) {
151-
if (PyFloat_Check(fastargs[9])) {
152-
PyErr_SetString(PyExc_TypeError,
153-
"integer argument expected, got float" );
154-
goto exit;
155-
}
156136
node_depth = _PyLong_AsInt(fastargs[9]);
157137
if (node_depth == -1 && PyErr_Occurred()) {
158138
goto exit;
@@ -162,11 +142,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
162142
}
163143
}
164144
if (fastargs[10]) {
165-
if (PyFloat_Check(fastargs[10])) {
166-
PyErr_SetString(PyExc_TypeError,
167-
"integer argument expected, got float" );
168-
goto exit;
169-
}
170145
inner_size = _PyLong_AsInt(fastargs[10]);
171146
if (inner_size == -1 && PyErr_Occurred()) {
172147
goto exit;
@@ -261,4 +236,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored))
261236
{
262237
return _blake2_blake2s_hexdigest_impl(self);
263238
}
264-
/*[clinic end generated code: output=39af5a74c8805b36 input=a9049054013a1b77]*/
239+
/*[clinic end generated code: output=ccaf156832fb9bce input=a9049054013a1b77]*/

Modules/_ctypes/cfield.c

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -353,14 +353,7 @@ PyTypeObject PyCField_Type = {
353353
static int
354354
get_long(PyObject *v, long *p)
355355
{
356-
long x;
357-
358-
if (PyFloat_Check(v)) {
359-
PyErr_SetString(PyExc_TypeError,
360-
"int expected instead of float");
361-
return -1;
362-
}
363-
x = PyLong_AsUnsignedLongMask(v);
356+
long x = PyLong_AsUnsignedLongMask(v);
364357
if (x == -1 && PyErr_Occurred())
365358
return -1;
366359
*p = x;
@@ -372,14 +365,7 @@ get_long(PyObject *v, long *p)
372365
static int
373366
get_ulong(PyObject *v, unsigned long *p)
374367
{
375-
unsigned long x;
376-
377-
if (PyFloat_Check(v)) {
378-
PyErr_SetString(PyExc_TypeError,
379-
"int expected instead of float");
380-
return -1;
381-
}
382-
x = PyLong_AsUnsignedLongMask(v);
368+
unsigned long x = PyLong_AsUnsignedLongMask(v);
383369
if (x == (unsigned long)-1 && PyErr_Occurred())
384370
return -1;
385371
*p = x;
@@ -391,13 +377,7 @@ get_ulong(PyObject *v, unsigned long *p)
391377
static int
392378
get_longlong(PyObject *v, long long *p)
393379
{
394-
long long x;
395-
if (PyFloat_Check(v)) {
396-
PyErr_SetString(PyExc_TypeError,
397-
"int expected instead of float");
398-
return -1;
399-
}
400-
x = PyLong_AsUnsignedLongLongMask(v);
380+
long long x = PyLong_AsUnsignedLongLongMask(v);
401381
if (x == -1 && PyErr_Occurred())
402382
return -1;
403383
*p = x;
@@ -409,13 +389,7 @@ get_longlong(PyObject *v, long long *p)
409389
static int
410390
get_ulonglong(PyObject *v, unsigned long long *p)
411391
{
412-
unsigned long long x;
413-
if (PyFloat_Check(v)) {
414-
PyErr_SetString(PyExc_TypeError,
415-
"int expected instead of float");
416-
return -1;
417-
}
418-
x = PyLong_AsUnsignedLongLongMask(v);
392+
unsigned long long x = PyLong_AsUnsignedLongLongMask(v);
419393
if (x == (unsigned long long)-1 && PyErr_Occurred())
420394
return -1;
421395
*p = x;

Modules/_io/clinic/_iomodule.c.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,6 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
178178
}
179179
}
180180
if (args[2]) {
181-
if (PyFloat_Check(args[2])) {
182-
PyErr_SetString(PyExc_TypeError,
183-
"integer argument expected, got float" );
184-
goto exit;
185-
}
186181
buffering = _PyLong_AsInt(args[2]);
187182
if (buffering == -1 && PyErr_Occurred()) {
188183
goto exit;
@@ -261,11 +256,6 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
261256
}
262257
}
263258
if (args[6]) {
264-
if (PyFloat_Check(args[6])) {
265-
PyErr_SetString(PyExc_TypeError,
266-
"integer argument expected, got float" );
267-
goto exit;
268-
}
269259
closefd = _PyLong_AsInt(args[6]);
270260
if (closefd == -1 && PyErr_Occurred()) {
271261
goto exit;
@@ -323,4 +313,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec
323313
exit:
324314
return return_value;
325315
}
326-
/*[clinic end generated code: output=3df6bc6d91697545 input=a9049054013a1b77]*/
316+
/*[clinic end generated code: output=5c0dd7a262c30ebc input=a9049054013a1b77]*/

Modules/_io/clinic/bufferedio.c.h

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,6 @@ _io__Buffered_peek(buffered *self, PyObject *const *args, Py_ssize_t nargs)
120120
if (nargs < 1) {
121121
goto skip_optional;
122122
}
123-
if (PyFloat_Check(args[0])) {
124-
PyErr_SetString(PyExc_TypeError,
125-
"integer argument expected, got float" );
126-
goto exit;
127-
}
128123
{
129124
Py_ssize_t ival = -1;
130125
PyObject *iobj = PyNumber_Index(args[0]);
@@ -200,11 +195,6 @@ _io__Buffered_read1(buffered *self, PyObject *const *args, Py_ssize_t nargs)
200195
if (nargs < 1) {
201196
goto skip_optional;
202197
}
203-
if (PyFloat_Check(args[0])) {
204-
PyErr_SetString(PyExc_TypeError,
205-
"integer argument expected, got float" );
206-
goto exit;
207-
}
208198
{
209199
Py_ssize_t ival = -1;
210200
PyObject *iobj = PyNumber_Index(args[0]);
@@ -356,11 +346,6 @@ _io__Buffered_seek(buffered *self, PyObject *const *args, Py_ssize_t nargs)
356346
if (nargs < 2) {
357347
goto skip_optional;
358348
}
359-
if (PyFloat_Check(args[1])) {
360-
PyErr_SetString(PyExc_TypeError,
361-
"integer argument expected, got float" );
362-
goto exit;
363-
}
364349
whence = _PyLong_AsInt(args[1]);
365350
if (whence == -1 && PyErr_Occurred()) {
366351
goto exit;
@@ -434,11 +419,6 @@ _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs)
434419
if (!noptargs) {
435420
goto skip_optional_pos;
436421
}
437-
if (PyFloat_Check(fastargs[1])) {
438-
PyErr_SetString(PyExc_TypeError,
439-
"integer argument expected, got float" );
440-
goto exit;
441-
}
442422
{
443423
Py_ssize_t ival = -1;
444424
PyObject *iobj = PyNumber_Index(fastargs[1]);
@@ -493,11 +473,6 @@ _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs)
493473
if (!noptargs) {
494474
goto skip_optional_pos;
495475
}
496-
if (PyFloat_Check(fastargs[1])) {
497-
PyErr_SetString(PyExc_TypeError,
498-
"integer argument expected, got float" );
499-
goto exit;
500-
}
501476
{
502477
Py_ssize_t ival = -1;
503478
PyObject *iobj = PyNumber_Index(fastargs[1]);
@@ -590,11 +565,6 @@ _io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs)
590565
if (PyTuple_GET_SIZE(args) < 3) {
591566
goto skip_optional;
592567
}
593-
if (PyFloat_Check(PyTuple_GET_ITEM(args, 2))) {
594-
PyErr_SetString(PyExc_TypeError,
595-
"integer argument expected, got float" );
596-
goto exit;
597-
}
598568
{
599569
Py_ssize_t ival = -1;
600570
PyObject *iobj = PyNumber_Index(PyTuple_GET_ITEM(args, 2));
@@ -649,11 +619,6 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs)
649619
if (!noptargs) {
650620
goto skip_optional_pos;
651621
}
652-
if (PyFloat_Check(fastargs[1])) {
653-
PyErr_SetString(PyExc_TypeError,
654-
"integer argument expected, got float" );
655-
goto exit;
656-
}
657622
{
658623
Py_ssize_t ival = -1;
659624
PyObject *iobj = PyNumber_Index(fastargs[1]);
@@ -672,4 +637,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs)
672637
exit:
673638
return return_value;
674639
}
675-
/*[clinic end generated code: output=7246104f6c7d3167 input=a9049054013a1b77]*/
640+
/*[clinic end generated code: output=056db07ecd9fdec4 input=a9049054013a1b77]*/

Modules/_io/clinic/bytesio.c.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -402,11 +402,6 @@ _io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs)
402402
if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) {
403403
goto exit;
404404
}
405-
if (PyFloat_Check(args[0])) {
406-
PyErr_SetString(PyExc_TypeError,
407-
"integer argument expected, got float" );
408-
goto exit;
409-
}
410405
{
411406
Py_ssize_t ival = -1;
412407
PyObject *iobj = PyNumber_Index(args[0]);
@@ -422,11 +417,6 @@ _io_BytesIO_seek(bytesio *self, PyObject *const *args, Py_ssize_t nargs)
422417
if (nargs < 2) {
423418
goto skip_optional;
424419
}
425-
if (PyFloat_Check(args[1])) {
426-
PyErr_SetString(PyExc_TypeError,
427-
"integer argument expected, got float" );
428-
goto exit;
429-
}
430420
whence = _PyLong_AsInt(args[1]);
431421
if (whence == -1 && PyErr_Occurred()) {
432422
goto exit;
@@ -515,4 +505,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs)
515505
exit:
516506
return return_value;
517507
}
518-
/*[clinic end generated code: output=4ec2506def9c8eb9 input=a9049054013a1b77]*/
508+
/*[clinic end generated code: output=ba0f302f16397741 input=a9049054013a1b77]*/

0 commit comments

Comments
 (0)