Skip to main content

A function decorator, that rewrites the bytecode, to enable goto in Python

Project description

goto

Build Status Pypi Entry

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

goto-statement-1.2.tar.gz (6.5 kB view details)

Uploaded Source

Built Distribution

goto_statement-1.2-py2.py3-none-any.whl (5.6 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file goto-statement-1.2.tar.gz.

File metadata

  • Download URL: goto-statement-1.2.tar.gz
  • Upload date:
  • Size: 6.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.6

File hashes

Hashes for goto-statement-1.2.tar.gz
Algorithm Hash digest
SHA256 e42e8c96dc24d5e8e2b1987c7c12335f73d0629852d121eac9e49bfa54514dce
MD5 785c11581cae5f68f57d1efc9bb6a281
BLAKE2b-256 82bef2c30d577110f05a3a9e97e84b586a1564f9abbb8f8317c92e0cad82e099

See more details on using hashes here.

File details

Details for the file goto_statement-1.2-py2.py3-none-any.whl.

File metadata

  • Download URL: goto_statement-1.2-py2.py3-none-any.whl
  • Upload date:
  • Size: 5.6 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.6

File hashes

Hashes for goto_statement-1.2-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 b087b365893da94745d5883b36eb42aa03fd204c479c333152a95ac24cc1321c
MD5 1d27d88e72ead9a090e0970b666fedc3
BLAKE2b-256 1cdaa9d93c0740c7af9f68f94036bb694c34414e8128fdc2af4bd56d07e6d7fd

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page