Package: goto-statement
gotoA function decorator to usegotoin Python.
Tested on Python 2.6 through 3.6 and PyPy.Installationpip install goto-statementUsagefromgotoimportwith_goto@with_gotodefrange(start,stop):i=startresult=[]label.beginifi==stop:goto.endresult.append(i)i+=1goto.beginlabel.endreturnresultImplementationNote thatlabel .beginandgoto .beginis regular Python syntax to retrieve
the attributebeginfrom the objects with the variable nameslabelandgoto. However, in the example above these variables aren't defined.
So this code would usually cause aNameError. But since it's valid
syntax the function can be parsed, and results in following bytecode:2           0 LOAD_FAST                0 (start)
              3 STORE_FAST               2 (i)

  3           6 BUILD_LIST               0
              9 STORE_FAST               3 (result)

  5          12 LOAD_GLOBAL              0 (label)
             15 LOAD_ATTR                1 (begin)
             18 POP_TOP

  6          19 LOAD_FAST                2 (i)
             22 LOAD_FAST                1 (stop)
             25 COMPARE_OP               2 (==)
             28 POP_JUMP_IF_FALSE       41

  7          31 LOAD_GLOBAL              2 (goto)
             34 LOAD_ATTR                3 (end)
             37 POP_TOP
             38 JUMP_FORWARD             0 (to 41)

  9     >>   41 LOAD_FAST                3 (result)
             44 LOAD_ATTR                4 (append)
             47 LOAD_FAST                2 (i)
             50 CALL_FUNCTION            1
             53 POP_TOP

 10          54 LOAD_FAST                2 (i)
             57 LOAD_CONST               1 (1)
             60 INPLACE_ADD
             61 STORE_FAST               2 (i)

 11          64 LOAD_GLOBAL              2 (goto)
             67 LOAD_ATTR                1 (begin)
             70 POP_TOP

 13          71 LOAD_GLOBAL              0 (label)
             74 LOAD_ATTR                3 (end)
             77 POP_TOP

 14          78 LOAD_FAST                3 (result)
             81 RETURN_VALUEThewith_gotodecorator then removes the respective bytecode that has been
generated for the attribute lookups of thelabelandgotovariables, and
injects aJUMP_ABSOLUTEinstruction for eachgoto:2           0 LOAD_FAST                0 (start)
              3 STORE_FAST               2 (i)

  3           6 BUILD_LIST               0
              9 STORE_FAST               3 (result)

  5          12 NOP
             13 NOP
             14 NOP
             15 NOP
             16 NOP
             17 NOP
             18 NOP

  6     >>   19 LOAD_FAST                2 (i)
             22 LOAD_FAST                1 (stop)
             25 COMPARE_OP               2 (==)
             28 POP_JUMP_IF_FALSE       41

  7          31 JUMP_ABSOLUTE           78
             34 NOP
             35 NOP
             36 NOP
             37 NOP
             38 JUMP_FORWARD             0 (to 41)

  9     >>   41 LOAD_FAST                3 (result)
             44 LOAD_ATTR                4 (append)
             47 LOAD_FAST                2 (i)
             50 CALL_FUNCTION            1
             53 POP_TOP

 10          54 LOAD_FAST                2 (i)
             57 LOAD_CONST               1 (1)
             60 INPLACE_ADD
             61 STORE_FAST               2 (i)

 11          64 JUMP_ABSOLUTE           19
             67 NOP
             68 NOP
             69 NOP
             70 NOP

 13          71 NOP
             72 NOP
             73 NOP
             74 NOP
             75 NOP
             76 NOP
             77 NOP

 14     >>   78 LOAD_FAST                3 (result)
             81 RETURN_VALUEAlternative implementationThe idea ofgotoin Python isn't new.
There isanother modulethat has been released
as April Fool's joke in 2004. That implementation doesn't touch the bytecode,
but uses a trace function, similar to how debuggers are written.While this eliminates the need for a decorator, it comes with significant
runtime overhead and a more elaborate implementation. Modifying the bytecode,
on the other hand, is fairly simple and doesn't add overhead at function
execution.