Author vstinner
Recipients vstinner, yselivanov
Date 2016-01-26.01:00:40
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1453770040.66.0.71475007122.issue26204@psf.upfronthosting.co.za>
In-reply-to
Content
The bytecode compilers ignores ast.Str and ast.Num nodes:

----------------------------
>>> def func():
...     123
...     "test"
... 
>>> import dis; dis.dis(func)
  3           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE
----------------------------

But other ast nodes which are constant are not ignored:

----------------------------
>>> def func2():
...     b'bytes'
...     (1, 2)
... 
>>> import dis; dis.dis(func2)
  2           0 LOAD_CONST               1 (b'bytes')
              3 POP_TOP

  3           4 LOAD_CONST               4 ((1, 2))
              7 POP_TOP
              8 LOAD_CONST               0 (None)
             11 RETURN_VALUE
----------------------------

I don't understand the point of loading a constant and then unload it (POP_TOP).


Attached patch changes the compiler to not emit LOAD_CONST+POP_TOP anymore.


My patch only affects constants. Example with the patch:
----------------------------
>>> def f():
...  x
... 
>>> import dis
>>> dis.dis(f)
  2           0 LOAD_GLOBAL              0 (x)
              3 POP_TOP
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE
----------------------------

The compiler still emits "LOAD_GLOBAL x" for the instruction "x".

Ignoring the Python instruction "x" would change the Python semantics, because the function would not raise a NameError anymore if x is not defined.

Note: I noticed this inefficient bytecode while working on the issue #26146 (add ast.Constant).
History
Date User Action Args
2016-01-26 01:00:40vstinnersetrecipients: + vstinner, yselivanov
2016-01-26 01:00:40vstinnersetmessageid: <1453770040.66.0.71475007122.issue26204@psf.upfronthosting.co.za>
2016-01-26 01:00:40vstinnerlinkissue26204 messages
2016-01-26 01:00:40vstinnercreate