classification
Title: Change in 3.7 expression evaluation?
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: eryksun, opstad
Priority: normal Keywords:

Created on 2018-07-24 14:21 by opstad, last changed 2018-07-24 14:47 by eryksun. This issue is now closed.

Messages (2)
msg322304 - (view) Author: Dave Opstad (opstad) Date: 2018-07-24 14:21
In 3.6 I get this:

>>> x = (100 * 20)
>>> x is 2000
False
>>> (100 * 20) is 2000
False

But in 3.7, I get this:

>>> x = (100 * 20)
>>> x is 2000
False
>>> (100 * 20) is 2000
True

This isn't necessarily a problem, but I'm curious why this behavior changed from 3.6 to 3.7.
msg322306 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2018-07-24 14:47
Please refrain from using the issue tracker to satisfy your curiosity. This is a question about compiler optimizations that should be asked on python-list, or maybe python-dev. 

You can use the dis module to get a superficial answer in terms of the constants in the code object. 

3.6:

    >>> dis.dis('(100 * 20) is 2000')
      1           0 LOAD_CONST               3 (2000)
                  2 LOAD_CONST               2 (2000)
                  4 COMPARE_OP               8 (is)
                  6 RETURN_VALUE

3.7:

    >>> dis.dis('(100 * 20) is 2000')
      1           0 LOAD_CONST               0 (2000)
                  2 LOAD_CONST               0 (2000)
                  4 COMPARE_OP               8 (is)
                  6 RETURN_VALUE

The argument of the LOAD_CONST opcode is the index of the constant in the code object's co_consts tuple. In 3.6 you can see it's separate int objects, but in 3.7 the operation uses the same int object (index 0).
History
Date User Action Args
2018-07-24 14:47:54eryksunsetstatus: open -> closed

nosy: + eryksun
messages: + msg322306

resolution: not a bug
stage: resolved
2018-07-24 14:21:42opstadcreate