Strange disassembly

Alan Bawden alan at csail.mit.edu
Sat Jun 19 22:07:12 EDT 2021


Chris Angelico <rosuav at gmail.com> writes:

   >>> sys.version
   '3.10.0b2+ (heads/3.10:33a7a24288, Jun  9 2021, 20:47:39) [GCC 8.3.0]'
   >>> def chk(x):
   ...     if not(0 < x < 10): raise Exception
   ...
   >>> dis.dis(chk)
     2           0 LOAD_CONST               1 (0)
                 2 LOAD_FAST                0 (x)
                 4 DUP_TOP
                 6 ROT_THREE
                 8 COMPARE_OP               0 (<)
                10 POP_JUMP_IF_FALSE       11 (to 22)
                12 LOAD_CONST               2 (10)
                14 COMPARE_OP               0 (<)
                16 POP_JUMP_IF_TRUE        14 (to 28)
                18 LOAD_GLOBAL              0 (Exception)
                20 RAISE_VARARGS            1
           >>   22 POP_TOP
                24 LOAD_GLOBAL              0 (Exception)
                26 RAISE_VARARGS            1
           >>   28 LOAD_CONST               0 (None)
                30 RETURN_VALUE
   >>>

   Why are there two separate bytecode blocks for the "raise Exception"?
   I'd have thought that the double condition would still be evaluated as
   one thing, or at least that the jump destinations for both the
   early-abort and the main evaluation should be the same.

Looks like in 3.8 it compiles more like the way you expected.

I didn't try 3.9, but it looks like a recent change to te compiler.


More information about the Python-list mailing list