On 18/06/2021 11:04, Chris Angelico wrote:
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.

ChrisA
As an ornery human I could refactor this to avoid the code duplication as

  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_TRUE        10 (to 18)
             12 POP_TOP
        >>   14 LOAD_GLOBAL              0 (Exception)
             16 RAISE_VARARGS            1
        >>   18 LOAD_CONST               2 (10)
             20 COMPARE_OP               0 (<)
             22 POP_JUMP_IF_FALSE       21 (to 14)
             24 LOAD_CONST               0 (None)
             26 RETURN_VALUE
>>>

(there may be mistakes in this) but this is probably too much to expect of the compiler.
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to