A function decorator, that rewrites the bytecode, to enable goto in Python
Project description
goto
A function decorator to use goto
in Python.
Tested on Python 2.6 through 3.6 and PyPy.
Installation
pip install goto-statement
Usage
from goto import with_goto
@with_goto
def range(start, stop):
i = start
result = []
label .begin
if i == stop:
goto .end
result.append(i)
i += 1
goto .begin
label .end
return result
Implementation
Note that label .begin
and goto .begin
is regular Python syntax to retrieve
the attribute begin
from the objects with the variable names label
and
goto
. However, in the example above these variables aren't defined.
So this code would usually cause a NameError
. 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_VALUE
The with_goto
decorator then removes the respective bytecode that has been
generated for the attribute lookups of the label
and goto
variables, and
injects a JUMP_ABSOLUTE
instruction for each goto
:
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_VALUE
Alternative implementation
The idea of goto
in Python isn't new.
There is another module that 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for goto_statement-1.2-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b087b365893da94745d5883b36eb42aa03fd204c479c333152a95ac24cc1321c |
|
MD5 | 1d27d88e72ead9a090e0970b666fedc3 |
|
BLAKE2b-256 | 1cdaa9d93c0740c7af9f68f94036bb694c34414e8128fdc2af4bd56d07e6d7fd |