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: is behave different for integers in 3.6 and 3.7
Type: Stage: resolved
Components: Interpreter Core Versions: Python 3.7, Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Geraldo.Xexeo, Shane Smith
Priority: normal Keywords:

Created on 2019-04-10 23:55 by Geraldo.Xexeo, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
testisbehavior.py Geraldo.Xexeo, 2019-04-10 23:55 A very simple example of the behavior
Messages (5)
msg339900 - (view) Author: Geraldo Xexeo (Geraldo.Xexeo) Date: 2019-04-10 23:55
# When you run the program:
a,b=300,300
print(a is b)
#you get different results in 3.6 (True) and 3.7 (False)
msg339902 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2019-04-11 00:01
Python makes no guarantee as to whether an identity test on integers would return True or False. You should not depend on the behavior in any particular version.
msg339905 - (view) Author: Shane (Shane Smith) Date: 2019-04-11 00:06
This is the sort of thing that makes me avoid "is" in favor of "==" for most applications.  Understanding when two objects point to the same memory requires a deeper understanding of the underlying code than I usually want to delve into.

Anyway, I find it interesting that for 3.7.3:
>>> a, b = 256, 256
>>> a is b
True

>>> a, b = 257, 257
>>> a is b
False


So 2**8 is a magic number, for whatever reason.  I'll be sticking with "=="...
msg339913 - (view) Author: Geraldo Xexeo (Geraldo.Xexeo) Date: 2019-04-11 01:31
"So 2**8 is a magic number, for whatever reason."

Actually, this is true. Accordingly to https://rushter.com/blog/python-integer-implementation/

"Optimization of commonly-used integers
Small integer objects in a range of -5 to 256 are always pre-allocated during initialization. Because Python integers are immutable, we can use them as singletons. Every time you need to create small integer instead of creating new object Python just points to already allocated one. Thereby it saves a lot of space and computation for commonly-used integers.

Interestingly enough, the PyLongObject structure takes at least 28 bytes for every allocated integer and therefore takes three times as much memory as a simple 64-bit C integer."

This are constants 

#define NSMALLPOSINTS           257
#define NSMALLNEGINTS           5

You can find the code in:

https://github.com/python/cpython/blob/master/Objects/longobject.c
msg339914 - (view) Author: Shane (Shane Smith) Date: 2019-04-11 01:52
Well, then I guess that explains it!  Still, like I said, I tend to shy away from features that require such a deep understanding of the implementation in order to avoid "gotchas".  "is" does have its uses, but for me they very very rarely come up.
History
Date User Action Args
2022-04-11 14:59:13adminsetgithub: 80773
2019-04-11 01:52:59Shane Smithsetmessages: + msg339914
2019-04-11 01:31:17Geraldo.Xexeosetmessages: + msg339913
2019-04-11 00:06:11Shane Smithsetnosy: + Shane Smith, - eric.smith
type: behavior ->
messages: + msg339905
2019-04-11 00:01:17eric.smithsetstatus: open -> closed

type: behavior

nosy: + eric.smith
messages: + msg339902
resolution: not a bug
stage: resolved
2019-04-10 23:55:24Geraldo.Xexeocreate