Skip to main content

goto

Build Status Pypi 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

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:

  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.

Metadata

Release files for goto-statement38 1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for goto-statement38 1.3
File Size Uploaded
goto-statement38-1.3.tar.gz 6.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for goto-statement38 1.3
File Interpreter ABI Platform
goto_statement38-1.3-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 12.7 kB

Release files / goto-statement38-1.3.tar.gz

Download URL goto-statement38-1.3.tar.gz
Size 6.9 kB
Tags Source
SHA-256 checksum
How to use checksums
98e8a0932ea7cda095c5919e588724060cfee1e5e286bddece3013d22cb93995
BLAKE2b-256 checksum
How to use checksums
310cd46d4f6359b72a29f9f9a861fd1748a7426ed2035115fd2695189d9310b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.8.10

Release files / goto_statement38-1.3-py2.py3-none-any.whl

Download URL goto_statement38-1.3-py2.py3-none-any.whl
Size 5.7 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
2a723a97eef3b00a6a455ff73610e7ec827e4aa878f41fd9a20d8c29456e22a2
BLAKE2b-256 checksum
How to use checksums
576f818d24cd3447ed3b8083c76d7ece8847932c3441fa5c807f154aa231a35e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.8.10

Release history Release notifications | RSS feed

This release

1.3 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page