Leap
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.
Examples
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
@goto
def print_list(lst):
i = 0
label .start
item = lst[i]
print(item)
if i == len(lst) - 1:
goto .end
else:
i += 1
goto .start
label .end
# test
print_list(range(5))
# this outputs
0
1
2
3
4
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
lst.append(val)
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
@goto(max_labels=2)
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
@goto(max_labels=3)
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
@goto(max_labels=2)
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?
Why not? I mean, it's a perfect excuse to test bytecode editing/rewriting possibilities in Python.
Tests
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
Limitations
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.
Installation
Clone this repo, and do:
cd leap
python setup.py install
Bugs/Features
Please file an issue.