This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Make int() fall back to trunc()
Type: behavior Stage:
Components: Versions: Python 3.0, Python 2.6
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: jyasskin Nosy List: gvanrossum, jyasskin, rhettinger
Priority: high Keywords: patch

Created on 2008-02-02 23:44 by jyasskin, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
int_fall_back_to_trunc.patch jyasskin, 2008-02-03 06:40
Messages (7)
msg62014 - (view) Author: Jeffrey Yasskin (jyasskin) * (Python committer) Date: 2008-02-02 23:44
Per http://mail.python.org/pipermail/python-dev/2008-January/076564.html.
msg62019 - (view) Author: Jeffrey Yasskin (jyasskin) * (Python committer) Date: 2008-02-03 06:40
Here's a patch to implement the fallback for both int and long. I'm
pretty sure that _PyNumber_ConvertIntegralToInt() is in the wrong place.
Where would be a better place for it?
msg62020 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2008-02-03 07:57
Guido, are these basically the mechanics you intended?  All calls to 
PyNumber_Int() and PyNumber_Long() attempt the usual path and if those 
would fail, it tries __trunc__ if it exists and coerces the result of 
that call back to an int or long.  

The logic looks basically correct, but I'm not sure what it buys us 
since the returned Integral has to be converted back to an int or long 
anyway.  On the plus side, it does not slow down the common case where 
PyNumber_Int() and PyNumberLong() would ordinarily succeed.  

An alternative to this patch would be to have math.trunc() try to 
return __trunc__() and if it doesn't exist, fallback to __int__.  That 
avoids having arbitrary Integrals forced back into ints/longs, but it 
may not be what you guys were after.

Either way will allow a user to define a __trunc__() method and have 
math.trunc() return an arbitrary Integral, not necessarily and int or 
long.

There is also part of this patch that touches classobject.c but I'm not 
yet sure what the visible effect of that change would be or what the 
change was hoping to accomplish.
msg62024 - (view) Author: Jeffrey Yasskin (jyasskin) * (Python committer) Date: 2008-02-03 18:12
> There is also part of this patch that touches classobject.c but I'm not
> yet sure what the visible effect of that change would be or what the
> change was hoping to accomplish.

All classic classes take the (m && m->nb_int) branch, so without the
change to classobject.c, they'd never hit the fallback to __trunc__.
The unfortunate side-effect is that when you call int() or long() on a
classic class without the right methods, you get an AttributeError
complaining about __trunc__ instead of about __int__. Since long()
already mistakenly complained about __int__, I didn't consider this a
showstopper, but it should be possible to fix if you want.
msg62030 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-02-04 00:41
> Guido, are these basically the mechanics you intended?  All calls to
> PyNumber_Int() and PyNumber_Long() attempt the usual path and if those
> would fail, it tries __trunc__ if it exists and coerces the result of
> that call back to an int or long.

Yes, that's exactly what I suggested.

> The logic looks basically correct, but I'm not sure what it buys us
> since the returned Integral has to be converted back to an int or long
> anyway.

Unless it's already an int or long. I would expect a type that wants
to play along with the ABCs defined in numbers.py will define
__trunc__ and not __int__ (since the latter isn't part of the ABC) but
it would have to be a pretty esoteric type not to return an int or
long.

> On the plus side, it does not slow down the common case where
> PyNumber_Int() and PyNumberLong() would ordinarily succeed.

Great -- so no penalty for builtin types.

> An alternative to this patch would be to have math.trunc() try to
> return __trunc__() and if it doesn't exist, fallback to __int__.  That
> avoids having arbitrary Integrals forced back into ints/longs, but it
> may not be what you guys were after.

Definitely not -- that would imply that math.trunc("42") would return
the integer 42!

> Either way will allow a user to define a __trunc__() method and have
> math.trunc() return an arbitrary Integral, not necessarily and int or
> long.

Correct, and that's as intended.

> There is also part of this patch that touches classobject.c but I'm not
> yet sure what the visible effect of that change would be or what the
> change was hoping to accomplish.

Looks like Jeffrey expained that already.
msg62031 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2008-02-04 00:44
Go for it.
msg62032 - (view) Author: Jeffrey Yasskin (jyasskin) * (Python committer) Date: 2008-02-04 01:05
Submitted as r60566.
History
Date User Action Args
2022-04-11 14:56:30adminsetgithub: 46286
2008-02-04 01:05:29jyasskinsetstatus: open -> closed
messages: + msg62032
2008-02-04 00:44:00rhettingersetassignee: gvanrossum -> jyasskin
resolution: accepted
messages: + msg62031
2008-02-04 00:41:40gvanrossumsetmessages: + msg62030
2008-02-03 18:12:42jyasskinsetmessages: + msg62024
2008-02-03 07:57:10rhettingersetassignee: jyasskin -> gvanrossum
messages: + msg62020
nosy: + gvanrossum
2008-02-03 06:40:08jyasskinsetkeywords: + patch
nosy: + rhettinger
messages: + msg62019
files: + int_fall_back_to_trunc.patch
2008-02-02 23:44:51jyasskincreate