{ "info": { "author": "Sebastian Noack", "author_email": "sebastian.noack@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: Public Domain", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# goto\n\n[![Build Status](https://travis-ci.org/snoack/python-goto.svg?branch=master)](https://travis-ci.org/snoack/python-goto)\n[![Pypi Entry](https://badge.fury.io/py/goto-statement.svg)](https://pypi.python.org/pypi/goto-statement)\n\nA function decorator to use `goto` in Python.\nTested on Python 2.6 through 3.6 and PyPy.\n\n[![](https://imgs.xkcd.com/comics/goto.png)](https://xkcd.com/292/)\n\n## Installation\n\n```\npip install goto-statement\n```\n\n## Usage\n\n```python\nfrom goto import with_goto\n\n@with_goto\ndef range(start, stop):\n i = start\n result = []\n\n label .begin\n if i == stop:\n goto .end\n\n result.append(i)\n i += 1\n goto .begin\n\n label .end\n return result\n```\n\n## Implementation\n\nNote that `label .begin` and `goto .begin` is regular Python syntax to retrieve\nthe attribute `begin` from the objects with the variable names `label` and\n`goto`. However, in the example above these variables aren't defined.\nSo this code would usually cause a `NameError`. But since it's valid\nsyntax the function can be parsed, and results in following bytecode:\n\n\n```\n 2 0 LOAD_FAST 0 (start)\n 3 STORE_FAST 2 (i)\n\n 3 6 BUILD_LIST 0\n 9 STORE_FAST 3 (result)\n\n 5 12 LOAD_GLOBAL 0 (label)\n 15 LOAD_ATTR 1 (begin)\n 18 POP_TOP\n\n 6 19 LOAD_FAST 2 (i)\n 22 LOAD_FAST 1 (stop)\n 25 COMPARE_OP 2 (==)\n 28 POP_JUMP_IF_FALSE 41\n\n 7 31 LOAD_GLOBAL 2 (goto)\n 34 LOAD_ATTR 3 (end)\n 37 POP_TOP\n 38 JUMP_FORWARD 0 (to 41)\n\n 9 >> 41 LOAD_FAST 3 (result)\n 44 LOAD_ATTR 4 (append)\n 47 LOAD_FAST 2 (i)\n 50 CALL_FUNCTION 1\n 53 POP_TOP\n\n 10 54 LOAD_FAST 2 (i)\n 57 LOAD_CONST 1 (1)\n 60 INPLACE_ADD\n 61 STORE_FAST 2 (i)\n\n 11 64 LOAD_GLOBAL 2 (goto)\n 67 LOAD_ATTR 1 (begin)\n 70 POP_TOP\n\n 13 71 LOAD_GLOBAL 0 (label)\n 74 LOAD_ATTR 3 (end)\n 77 POP_TOP\n\n 14 78 LOAD_FAST 3 (result)\n 81 RETURN_VALUE\n```\n\nThe `with_goto` decorator then removes the respective bytecode that has been\ngenerated for the attribute lookups of the `label` and `goto` variables, and\ninjects a `JUMP_ABSOLUTE` instruction for each `goto`:\n\n```\n 2 0 LOAD_FAST 0 (start)\n 3 STORE_FAST 2 (i)\n\n 3 6 BUILD_LIST 0\n 9 STORE_FAST 3 (result)\n\n 5 12 NOP\n 13 NOP\n 14 NOP\n 15 NOP\n 16 NOP\n 17 NOP\n 18 NOP\n\n 6 >> 19 LOAD_FAST 2 (i)\n 22 LOAD_FAST 1 (stop)\n 25 COMPARE_OP 2 (==)\n 28 POP_JUMP_IF_FALSE 41\n\n 7 31 JUMP_ABSOLUTE 78\n 34 NOP\n 35 NOP\n 36 NOP\n 37 NOP\n 38 JUMP_FORWARD 0 (to 41)\n\n 9 >> 41 LOAD_FAST 3 (result)\n 44 LOAD_ATTR 4 (append)\n 47 LOAD_FAST 2 (i)\n 50 CALL_FUNCTION 1\n 53 POP_TOP\n\n 10 54 LOAD_FAST 2 (i)\n 57 LOAD_CONST 1 (1)\n 60 INPLACE_ADD\n 61 STORE_FAST 2 (i)\n\n 11 64 JUMP_ABSOLUTE 19\n 67 NOP\n 68 NOP\n 69 NOP\n 70 NOP\n\n 13 71 NOP\n 72 NOP\n 73 NOP\n 74 NOP\n 75 NOP\n 76 NOP\n 77 NOP\n\n 14 >> 78 LOAD_FAST 3 (result)\n 81 RETURN_VALUE\n```\n\n## Alternative implementation\n\nThe idea of `goto` in Python isn't new.\nThere is [another module](http://entrian.com/goto/) that has been released\nas April Fool's joke in 2004. That implementation doesn't touch the bytecode,\nbut uses a trace function, similar to how debuggers are written.\n\nWhile this eliminates the need for a decorator, it comes with significant\nruntime overhead and a more elaborate implementation. Modifying the bytecode,\non the other hand, is fairly simple and doesn't add overhead at function\nexecution.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/snoack/python-goto/", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "goto-statement", "package_url": "https://pypi.org/project/goto-statement/", "platform": "", "project_url": "https://pypi.org/project/goto-statement/", "project_urls": { "Homepage": "https://github.com/snoack/python-goto/" }, "release_url": "https://pypi.org/project/goto-statement/1.2/", "requires_dist": null, "requires_python": "", "summary": "A function decorator, that rewrites the bytecode, to enable goto in Python", "version": "1.2" }, "last_serial": 4644588, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "f316393d8186f60bbe18ae513aba7c9e", "sha256": "b19d289eff862dc507ea53f78c197ea998b833705174171b01c260d40a9f037f" }, "downloads": -1, "filename": "goto_statement-1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f316393d8186f60bbe18ae513aba7c9e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 3893, "upload_time": "2017-01-20T13:24:58", "url": "https://files.pythonhosted.org/packages/33/73/31949da34cba8f21f0dfb749bcd7228045cd74d392a18aa4c1d650c8b1fa/goto_statement-1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d1f7e2e96aee40a2f346e526c95f3d66", "sha256": "c60f90023c3a0f968a47206abb74bbc06937286141f9eeaba16a8bc75b687791" }, "downloads": -1, "filename": "goto-statement-1.0.tar.gz", "has_sig": false, "md5_digest": "d1f7e2e96aee40a2f346e526c95f3d66", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2556, "upload_time": "2017-01-20T11:45:02", "url": "https://files.pythonhosted.org/packages/aa/23/d31943784d0b553c956b12bac46b31362a5e8a0fc8905e51b5b15fc6db31/goto-statement-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "cfc03d96a7c57bab0cd1fa00f7d8dbc0", "sha256": "044c2510309801ea793a226f174d7fe93ead5f7de8b0ecb684a41ea71db3cf56" }, "downloads": -1, "filename": "goto_statement-1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cfc03d96a7c57bab0cd1fa00f7d8dbc0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 4301, "upload_time": "2017-01-23T13:39:58", "url": "https://files.pythonhosted.org/packages/37/1c/8f2b705a6364eb2d8c2e095e7aa8d9d4662d2e47b262a0160761e0ff88cf/goto_statement-1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "884db79cea08bbf688ec2c17bc9905b6", "sha256": "ec79467d0ee6e931f08bc0a27d01724e9f627945b30ee6e179ae92487ac54754" }, "downloads": -1, "filename": "goto-statement-1.1.tar.gz", "has_sig": false, "md5_digest": "884db79cea08bbf688ec2c17bc9905b6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2972, "upload_time": "2017-01-23T13:39:59", "url": "https://files.pythonhosted.org/packages/08/69/39aae58a2bc9ac6ff9db226acc2cb3a87a5237e3e7eeb05e3b1011a6f4f6/goto-statement-1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "1d27d88e72ead9a090e0970b666fedc3", "sha256": "b087b365893da94745d5883b36eb42aa03fd204c479c333152a95ac24cc1321c" }, "downloads": -1, "filename": "goto_statement-1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1d27d88e72ead9a090e0970b666fedc3", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 5625, "upload_time": "2018-12-29T19:18:25", "url": "https://files.pythonhosted.org/packages/1c/da/a9d93c0740c7af9f68f94036bb694c34414e8128fdc2af4bd56d07e6d7fd/goto_statement-1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "785c11581cae5f68f57d1efc9bb6a281", "sha256": "e42e8c96dc24d5e8e2b1987c7c12335f73d0629852d121eac9e49bfa54514dce" }, "downloads": -1, "filename": "goto-statement-1.2.tar.gz", "has_sig": false, "md5_digest": "785c11581cae5f68f57d1efc9bb6a281", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6501, "upload_time": "2018-12-29T19:18:26", "url": "https://files.pythonhosted.org/packages/82/be/f2c30d577110f05a3a9e97e84b586a1564f9abbb8f8317c92e0cad82e099/goto-statement-1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1d27d88e72ead9a090e0970b666fedc3", "sha256": "b087b365893da94745d5883b36eb42aa03fd204c479c333152a95ac24cc1321c" }, "downloads": -1, "filename": "goto_statement-1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1d27d88e72ead9a090e0970b666fedc3", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 5625, "upload_time": "2018-12-29T19:18:25", "url": "https://files.pythonhosted.org/packages/1c/da/a9d93c0740c7af9f68f94036bb694c34414e8128fdc2af4bd56d07e6d7fd/goto_statement-1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "785c11581cae5f68f57d1efc9bb6a281", "sha256": "e42e8c96dc24d5e8e2b1987c7c12335f73d0629852d121eac9e49bfa54514dce" }, "downloads": -1, "filename": "goto-statement-1.2.tar.gz", "has_sig": false, "md5_digest": "785c11581cae5f68f57d1efc9bb6a281", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6501, "upload_time": "2018-12-29T19:18:26", "url": "https://files.pythonhosted.org/packages/82/be/f2c30d577110f05a3a9e97e84b586a1564f9abbb8f8317c92e0cad82e099/goto-statement-1.2.tar.gz" } ] }