id returns a Python int object (the memory address of the id -ing object, although this is an implementation detail). But besides a very small int (again, implementation details), Python does not have int caching; if you compute the same int two ways, these are two different int objects that have the same value. Similarly, each time id is called, a new int is created, even if the objects are the same.
The equivalence for id and is is that a is b means id(a) == id(b) , not id(a) is id(b) (and in fact, since id are large numbers, id(a) is id(b) almost always False ).
Also note that your test case is corrupted in other ways:
a = 3 b = 3 a is b
returns True for comparison is due to the small int cache in CPython; if you did:
a = 1000 b = 1000 a is b
a is b will be False ; your identity assumptions are only saved in CPython for numbers ranging from -5 to 256 inclusive, which are singles for performance reasons, but all other ints are recreated as needed, not single ones.
Shadowranger
source share