classification
Title: [py3k] Integer floor division (//): small int check omitted
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.0
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Rhamphoryncus, belopolsky, duncanb, facundobatista, pitrou, terry.reedy
Priority: normal Keywords: patch

Created on 2008-03-19 04:45 by terry.reedy, last changed 2008-07-24 18:57 by facundobatista. This issue is now closed.

Files
File name Uploaded Description Edit
issue2417.diff belopolsky, 2008-03-19 23:07
issue2417a.diff belopolsky, 2008-03-20 04:46 Patch against revision 61624
issue2417b.diff belopolsky, 2008-07-24 02:26 Patch against revision 65210
Messages (13)
msg64037 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2008-03-19 04:45
Python 3.0a3 (r30a3:61161, Mar  1 2008, 22:51:17) [MSC v.1500 32 bit
(Intel)] on win32

>>> a,b=1,1//1
>>> a is b
False

IDLE 3.0a3 
>>> a,b=1,1//1
>>> a is b
True

ditto for 2.5.2 interpreter   

On c.l.p, Duncan Booth wrote
I've had a look to see why this happens: long division (and in Python 3
all integers are longs) allocates a new long to hold the result of the
division so it will never use one of the preallocated 'small int' values.

That maybe explains the change from 2.5 but not the difference from
IDLE.  More important, the small int checks are present with the other
operations:
>>> 1*1 is 1
True
>>> 1+1 is 2
True
>>> 1-1 is 0
True
>>> 1**1 is 1
True

so the omission with // is plausibly a bug.
msg64060 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-03-19 15:13
I agree this is a bug.  Here is a related problem:

>>> 1 is divmod(1,1)[0]
False
msg64063 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-03-19 15:49
>>> int('1') is 1
False
>>> 1 is int('0b1', 2)
False
>>> 1 is 0b10000 >> 4
False

there are probably more ...
msg64064 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-03-19 15:57
>>> 1 is 1|1
False
>>> 1 is 1&1
False
>>> 0 is 1^1
False
>>> 2 is 1<<1
False
msg64065 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2008-03-19 16:06
I really don't understand *why* it's a bug.

Is anywhere in the Language Reference that says that 1 should be the
same object that another 1?

Or do you mean that they *should* be the same object for speed and/or
memory reasons? In this case... is this a bug? Or a request for
improvement or something?
msg64066 - (view) Author: Adam Olsen (Rhamphoryncus) Date: 2008-03-19 16:19
The original bug is not whether or not python reuses int objects, but
rather that an existing optimization disappears under certain
circumstances.  Something is breaking our optimization.

The later cases where the optimization is simply gone in 3.0a3 are more
difficult.  We don't *have* to keep them.. but we probably want them. 
The small int reuse happens for a reason.
msg64090 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2008-03-19 19:33
I agree that this is not a bug in the strict sense.  I could have
selected Type: resource usage (for memory increase).  But the change of
behavior is also visible.  I suspect the change is not intentional both
because of the pattern and because of recent discussion on PyDev that
small int caching should be kept.

If the precise change is intentional, this should be documented (here)
to answer further questions on c.l.p.
msg64119 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-03-19 23:07
Attached patch fixes the cases discovered so far.  It is possible that 
in some of these cases creation of the long object that is later 
discarded can be avoided by detecting small int return early, but such 
optimizations should probably be left for later.

Any advise on how to write a unit test?  Should the unit test detect 
python compiled with NSMALLNEGINTS + NSMALLPOSINTS == 0 and disable 
identity checks?
msg64122 - (view) Author: Adam Olsen (Rhamphoryncus) Date: 2008-03-19 23:25
Unless someone has a legitimate use case for disabling small_int that
doesn't involve debugging (which I really doubt), I'd just assume it's
always in use.
msg64150 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-03-20 04:46
Attached (issue2417a.diff) patch adds unit tests and fixes a few corner 
cases when a non-preallocated 0 was returned to python.
msg70185 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2008-07-24 01:09
Alexander, tried the issue2417a.diff patch against 65210, and does not
apply cleanly, could you please submit an updated one?

Thanks!
msg70188 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-07-24 02:26
It looks like e-mail submission did not work.  Uploading updated patch as issue2417b.diff .
msg70220 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2008-07-24 18:57
Commited in r65220.

Thank you everybody!!
History
Date User Action Args
2008-07-24 18:57:36facundobatistasetstatus: open -> closed
resolution: fixed
messages: + msg70220
2008-07-24 02:26:52belopolskysetfiles: + issue2417b.diff
messages: + msg70188
2008-07-24 01:09:10facundobatistasetmessages: + msg70185
2008-07-23 15:11:05pitrousetpriority: normal
nosy: + pitrou
2008-03-20 04:46:29belopolskysetfiles: + issue2417a.diff
messages: + msg64150
2008-03-19 23:25:22Rhamphoryncussetmessages: + msg64122
2008-03-19 23:07:18belopolskysetfiles: + issue2417.diff
keywords: + patch
messages: + msg64119
2008-03-19 19:33:31terry.reedysetmessages: + msg64090
2008-03-19 16:19:49Rhamphoryncussetnosy: + Rhamphoryncus
messages: + msg64066
2008-03-19 16:06:25facundobatistasetnosy: + facundobatista
messages: + msg64065
2008-03-19 15:57:42belopolskysetmessages: + msg64064
2008-03-19 15:49:48belopolskysetmessages: + msg64063
2008-03-19 15:13:37belopolskysetnosy: + belopolsky
messages: + msg64060
2008-03-19 09:31:19duncanbsetnosy: + duncanb
2008-03-19 04:54:53terry.reedysettitle: Integer floor division (//): small int check omitted -> [py3k] Integer floor division (//): small int check omitted
2008-03-19 04:45:56terry.reedycreate