Metadata-Version: 2.1
Name: goto-statement
Version: 1.2
Summary: A function decorator, that rewrites the bytecode, to enable goto in Python
Home-page: https://github.com/snoack/python-goto/
Author: Sebastian Noack
Author-email: sebastian.noack@gmail.com
License: UNKNOWN
Description: # goto
        
        [![Build Status](https://travis-ci.org/snoack/python-goto.svg?branch=master)](https://travis-ci.org/snoack/python-goto)
        [![Pypi Entry](https://badge.fury.io/py/goto-statement.svg)](https://pypi.python.org/pypi/goto-statement)
        
        A function decorator to use `goto` in Python.
        Tested on Python 2.6 through 3.6 and PyPy.
        
        [![](https://imgs.xkcd.com/comics/goto.png)](https://xkcd.com/292/)
        
        ## Installation
        
        ```
        pip install goto-statement
        ```
        
        ## Usage
        
        ```python
        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](http://entrian.com/goto/) 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.
        
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: Public Domain
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Description-Content-Type: text/markdown
