Search code examples
pythonpython-3.xinternals

inconsistency in "is" behavior over immutable objects in python 3.6 and older vs 3.7


I was introducing is operator to my students when I noticed that there is an inconsistency in its behavior between python (v3.6 and older) and (v3.7).

Launch a python shell and run:

5/2 is 2.5

Or:

(1, 2, 3) is (1, 2, 3)

in v3.6.X you get False for both, but in v3.7 they turn out to be True.

My expectation was that the result should be True as I thought immutable numeric objects (or a tuple of them) have just one instance.

It seems that at least my thought was not right in the previous versions of Python.

Does anyone know what changes have been made which explains this new behaviour?


Solution

  • I'm not sure about reasons and source for this, but my guess is that this has something to do with in-line optimizations.

    If you'll assign variable for this values, identity check will result in False, same as before.

    >>> 5/2 is 2.5
    True
    >>> a = 5/2
    >>> a is 2.5
    False
    

    Interesting note on new folding optimisation. As python is "all runtime", there's no way to optimize some things ahead, but it tries hard, parsing as much scope as it can:

    >>> a = 3.14
    >>> b = 3.14
    >>> a is b
    False
    >>> a = 3.14; b = 3.14
    >>> a is b
    True