Leap is an experimental package written to enable the utilization of C-like goto statements in Python functions. It currently supports only Python 3.6 and 3.7.


Labels are added using a label keyword, and gotos are added using a goto keyword.
Here is a simple function that prints the contents of a list, using the goto keyword.

from leap.goto import goto

def print_list(lst):
    i = 0
    label .start
    item = lst[i]
    if i == len(lst) - 1:
        goto .end
        i += 1
        goto .start
    label .end

# test

# this outputs

We can also utilize the goto decorator, if we need to pass arguments, to perform checks.

Below is a simple function that builds a list given a start value an end value, and an optional step value.
Here, formal arguments max_gotos and max_labels are sentries that ensures the maximum number of goto
and label statements in build_list() does not exceed the actual parameter values. If it does, an exception is raised accordingly.

debug (False by default, only explicitly declared for example sake) is also set to False to disable internal-processing outputs.

from leap.goto import goto

@goto(debug=False, max_gotos=3, max_labels=3)
def build_list(begin_val, end_val, step=1):
    lst = []
    val = begin_val
    label .begin
    if val >= end_val:
        goto .end
    val += step
    goto .begin
    label .end
    return lst

print(build_list(1, 10))  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Below is a simple function err() that will fail at decoration time.

from leap.goto import goto

def err():
    label .start1
    label .start2
    label .start3

# Traceback (most recent call last):
# ...
# LabelLimitError: Too many labels in function. Max allowed: 2

The exception was triggered because max_labels was exceeded. The same applies to goto statements (in this case we have a GotoLimitError).

Duplicate labels are also not allowed (this can lead to some form of ambiguity).

from leap.goto import goto

def err2():
    label .start
    label .start

# Traceback (most recent call last):
# ...
# DuplicateLabelError: Duplicate labels found: `start`

Labels that are not declared in a function cannot be referenced in a goto statement.

Below is a simple example that will fail.

from leap.goto import goto

def err3():
    x = 0
    goto .end
    label .start

# Traceback (most recent call last):
# ...
# LabelNotFoundError: Label `end` was not found.

Functions err(), err2(), and err3() will fail even before any of them are called.


Why not? I mean, it's a perfect excuse to test bytecode editing/rewriting possibilities in Python.


See the tests folder for tests and other examples.
To run the tests, simply cd to the Leap directory, and do:
python -m tests.test -v


Only functions/methods are supported (may be easily inferable from the decorator syntax).
Nested functions/methods are not supported, that is, labels cannot be declared in external or enclosing functions and referenced in another function be it inner or enclosing.


Clone this repo, and do:

cd leap
python setup.py install


Please file an issue.



GitHub - ziord/leap at pythonawesome.com
C-like goto construct in python. Contribute to ziord/leap development by creating an account on GitHub.