{ "info": { "author": "Tiago Coutinho", "author_email": "coutinhotiago@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries", "Topic :: Utilities" ], "description": "# gtools\n\nA python library providing [gevent](http://www.gevent.org) tools:\n\n* a gevent friendly pdb\n* tree representation of running greenlets\n\n\n## Gevent friendly pdb\n\nThe *standard* python `pdb` module blocks all greenlets at the pdb prompt\n(unlike a threaded app). If you want your greenlets to run in the background\nyou can use `gtools.pdb` instead.\n\nIt can be used like the standard `pdb`.\n\nSo, imagine you have a gevent app that you want to debug:\n\n```python\n# ======\n# app.py\n# ======\n\nimport gevent\n\ndef produce(p):\n for i in range(60):\n p.append(i)\n gevent.sleep(1)\n\nproducts = []\ngevent.spawn(produce, products)\n```\n\nto debug it just type on the console:\n\n```bash\n$ python -m gtools.pdb app.py\n```\n\nThen hit '**n**' until you reach the `task.join()` line. At this point the\ngreenlet is already doing its work on the background. To make sure just type\n*products* several times on the pdb console and you will see the products list\nbeing filled by the running greenlet:\n\n```bash\n> /app.py(9)()\n-> gevent.spawn(produce, products)\n(Pdb) products\n[0, 1, 2]\n(Pdb) products\n[0, 1, 2, 3, 4, 5, 6, 7]\n```\n\nUse `gtools.pdb.set_trace()` just as you would with the standard\n`pdb.set_trace()`\n\n## Monitoring greenlets\n\n`gtools.tree.Tree()` allows you to trace the current greenlets and display them\nin a tree like structure:\n\n```python\n\n>>> import gevent\n>>> import gtools.tree\n\n>>> def iloop():\n... gevent.sleep(1)\n\n>>> def oloop():\n... gtools.spawn(iloop)\n... gevent.sleep(0.5)\n\n>>> task = gtools.spawn(oloop)\n\n>>> # sleep just to trigger spawn of inner greenlets\n>>> gevent.sleep()\n>>> tree = gtools.tree.Tree()\n\n>>> # initial status\n>>> print(tree)\nRoot\n\u2514\u2500 status=running\n \u2514\u2500 status=running\n \u2514\u2500 status=running\n\n>>> # after outer loop finishes\n>>> gevent.sleep(0.6)\n>>> print(tree)\nRoot\n\u2514\u2500 status=running\n \u2514\u2500 status=finished:success\n \u2514\u2500 status=running\n\n>>> # after inner loop finishes\n>>> gevent.sleep(0.6)\n>>> print(tree)\nRoot\n\u2514\u2500 status=running\n \u2514\u2500 status=finished:success\n \u2514\u2500 status=dead:garbage collected\n\n>>> del task\n\n>>> # when there are no more references to the greenlets\n>>> print(tree)\nRoot\n\u2514\u2500 status=running\n \u2514\u2500 status=dead:garbage collected\n \u2514\u2500 status=dead:garbage collected\n\n>>>\n>>> # new tree\n>>> print(gtools.tree.Tree())\nRoot\n```\n\nThe above example requires the usage of `gtools.Greenlet`.\n\nTo trace greenlets from an existing gevent application you simply need to\n*monkey-patch* gevent itself **before** importing your app:\n\n```python\n# ======\n# app.py\n# ======\n\nimport gevent\n\ndef iloop():\n gevent.sleep(1)\n\ndef oloop():\n gevent.spawn(iloop)\n gevent.sleep(0.5)\n\ndef run():\n return gevent.spawn(oloop)\n```\n\n```python\n>>> from gtools.monkey import patch_gevent\n>>> patch_gevent()\n>>> import app\n>>> import gtools.tree\n\n>>> the_app = app.run()\n\n>>> # sleep just to trigger spawn of inner greenlets\n>>> gevent.sleep()\n>>> tree = gtools.tree.Tree()\n\n>>> # initial status\n>>> print(tree)\nRoot\n\u2514\u2500 status=running\n \u2514\u2500 status=running\n \u2514\u2500 status=running\n```\n\nIf you don't monkey patch, you can still have limited information about the\nrunning greenlets (notice that the tree hierarchy is lost):\n\n```python\n\n>>> import app\n>>> import gtools.tree\n>>> task = gevent.spawn(oloop)\n\n>>> the_app = app.run()\n\n>>> # sleep just to trigger spawn of inner greenlets\n>>> gevent.sleep()\n>>> tree = gtools.tree.Tree(all=True)\n\n>>> # initial status\n>>> print(tree)\nRoot\n\u2514\u2500 status=running\n \u2514\u2500 status=running\n \u251c\u2500 status=running\n \u2514\u2500 status=running\n```\n\nIt can even trace greenlets across multiple threads (see\n`examples/tree_threads.py`)", "description_content_type": "", "docs_url": null, "download_url": "http://pypi.python.org/pypi/gevent-tools", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/tiagocoutinho/gtools", "keywords": "gevent,tools", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "gevent-tools", "package_url": "https://pypi.org/project/gevent-tools/", "platform": "Linux", "project_url": "https://pypi.org/project/gevent-tools/", "project_urls": { "Download": "http://pypi.python.org/pypi/gevent-tools", "Homepage": "https://github.com/tiagocoutinho/gtools" }, "release_url": "https://pypi.org/project/gevent-tools/0.2.0/", "requires_dist": null, "requires_python": "", "summary": "gevent utilities library", "version": "0.2.0" }, "last_serial": 3679454, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "5dde902d6ff72ce1f69a7955d63c7bcc", "sha256": "557a05520eed11de557569b2fcf6cc65001f49618fc230c96431b43a7b042e43" }, "downloads": -1, "filename": "gevent-tools-0.1.0.tar.gz", "has_sig": false, "md5_digest": "5dde902d6ff72ce1f69a7955d63c7bcc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3725, "upload_time": "2017-01-11T11:22:26", "url": "https://files.pythonhosted.org/packages/a2/a3/de281b03bae8b1af88c01f5630b5e35cabf43fe454d7f13b3938b077cf4d/gevent-tools-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "6611472119bb39c7c538636c120d75e0", "sha256": "9b4c72001daeb73b7ba8d056aa18d99da8fad87a3e3246606313207e68b21e01" }, "downloads": -1, "filename": "gevent-tools-0.1.1.tar.gz", "has_sig": false, "md5_digest": "6611472119bb39c7c538636c120d75e0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3679, "upload_time": "2017-01-11T11:42:48", "url": "https://files.pythonhosted.org/packages/94/4d/e16026b43117532f4e9f659af0f6269181b1cf60572a66ef58ba48ac8926/gevent-tools-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "211b6045093f132bab57396865f8158e", "sha256": "8a98d82a7088c68666294eb7f8b79e76153d3a02fb4ad0e871250f05415b507d" }, "downloads": -1, "filename": "gevent-tools-0.2.0.tar.gz", "has_sig": false, "md5_digest": "211b6045093f132bab57396865f8158e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6763, "upload_time": "2018-03-17T19:49:25", "url": "https://files.pythonhosted.org/packages/fe/65/e491183ccd4772cec5797d0bfa1d6b1e685ab5ca79afb95486982197b7ce/gevent-tools-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "211b6045093f132bab57396865f8158e", "sha256": "8a98d82a7088c68666294eb7f8b79e76153d3a02fb4ad0e871250f05415b507d" }, "downloads": -1, "filename": "gevent-tools-0.2.0.tar.gz", "has_sig": false, "md5_digest": "211b6045093f132bab57396865f8158e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6763, "upload_time": "2018-03-17T19:49:25", "url": "https://files.pythonhosted.org/packages/fe/65/e491183ccd4772cec5797d0bfa1d6b1e685ab5ca79afb95486982197b7ce/gevent-tools-0.2.0.tar.gz" } ] }