Skip to content
This repository was archived by the owner on Jul 28, 2026. It is now read-only.

Repository files navigation

goto

Warning

This project is discontinued and no longer supported.

It works by rewriting CPython bytecode and was designed for Python 2.6 through 3.7. Python's bytecode and code object APIs have changed substantially since then, and the package is not compatible with current Python releases. This repository is preserved for historical reference; no compatibility updates, fixes, or releases are planned.

Build StatusPypi Entry

A function decorator to use goto in Python. Tested on Python 2.6 through 3.7 and PyPy.

Installation

pip install goto-statement

Usage

fromgotoimportwith_goto@with_gotodefrange(start, stop):
i=startresult= []
label .beginifi==stop:
goto .endresult.append(i)
i+=1goto .beginlabel .endreturnresult

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:

 5 0 LOAD_FAST 0 (start)
2 STORE_FAST 2 (i)
6 4 BUILD_LIST 0
6 STORE_FAST 3 (result)
8 8 LOAD_GLOBAL 0 (label)
10 LOAD_ATTR 1 (begin)
12 POP_TOP
9 14 LOAD_FAST 2 (i)
16 LOAD_FAST 1 (stop)
18 COMPARE_OP 2 (==)
20 POP_JUMP_IF_FALSE 28
10 22 LOAD_GLOBAL 2 (goto)
24 LOAD_ATTR 3 (end)
26 POP_TOP
12 >> 28 LOAD_FAST 3 (result)
30 LOAD_METHOD 4 (append)
32 LOAD_FAST 2 (i)
34 CALL_METHOD 1
36 POP_TOP
13 38 LOAD_FAST 2 (i)
40 LOAD_CONST 1 (1)
42 INPLACE_ADD
44 STORE_FAST 2 (i)
14 46 LOAD_GLOBAL 2 (goto)
48 LOAD_ATTR 1 (begin)
50 POP_TOP
16 52 LOAD_GLOBAL 0 (label)
54 LOAD_ATTR 3 (end)
56 POP_TOP
17 58 LOAD_FAST 3 (result)
60 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 or JUMP_RELATIVE instruction for each goto:

 5 0 LOAD_FAST 0 (start)
2 STORE_FAST 2 (i)
6 4 BUILD_LIST 0
6 STORE_FAST 3 (result)
8 8 NOP
10 NOP
12 NOP
9 >> 14 LOAD_FAST 2 (i)
16 LOAD_FAST 1 (stop)
18 COMPARE_OP 2 (==)
20 POP_JUMP_IF_FALSE 28
10 22 JUMP_FORWARD 34 (to 58)
24 NOP
26 NOP
12 >> 28 LOAD_FAST 3 (result)
30 LOAD_METHOD 4 (append)
32 LOAD_FAST 2 (i)
34 CALL_METHOD 1
36 POP_TOP
13 38 LOAD_FAST 2 (i)
40 LOAD_CONST 1 (1)
42 INPLACE_ADD
44 STORE_FAST 2 (i)
14 46 JUMP_ABSOLUTE 14
48 NOP
50 NOP
16 52 NOP
54 NOP
56 NOP
17 >> 58 LOAD_FAST 3 (result)
60 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.

About

Discontinued function decorator that rewrites Python bytecode to enable goto statements

Resources

Stars

1.3k stars

Watchers

19 watching

Forks

Releases

Packages

Used by

Contributors

Languages