{ "info": { "author": "Zach Banks", "author_email": "zbanks@mit.edu", "bugtrack_url": null, "classifiers": [], "description": "#doitlive\r\n=========\r\n\r\n#doitlive - Tools for livecoding performances in Python.\r\n\r\n#doitlive allows you to \"refresh\" a class by reloading the source in an\r\n*almost*-sane and *almost*-safe way. It also provides facilities for\r\ncatching and handling common errors that come up with livecoding, such\r\nas undeclared variables.\r\n\r\nIt works under the philosophy that it's better to have weird behavior\r\nthan to crash.\r\n\r\nBesides livecoding, it can also be used as a tool for debugging or\r\nexperimenting -- you can tweak algorithms as they run.\r\n\r\nProjects\r\n--------\r\n\r\n- https://github.com/zbanks/beetle\r\n- https://github.com/ervanalb/beat-off/tree/live\r\n- https://github.com/zbanks/aurora\r\n- https://github.com/zbanks/peebles\r\n- https://github.com/ervanalb/noise\r\n\r\nInstallation\r\n------------\r\n\r\nInstall from pip:\r\n\r\n::\r\n\r\n pip install refreshable\r\n\r\nOr install the latest *(ha!)* from git:\r\n\r\n::\r\n\r\n git clone https://github.com/zbanks/doitlive.git\r\n cd doitlive\r\n python setup.py install\r\n\r\nrefreshable.SafeRefreshableMixin\r\n--------------------------------\r\n\r\nProvides a ``.refresh()`` method to reload a class\r\n\r\nAdding the ``SafeRefreshMixin`` to a class allows you to \"refresh\" the\r\nclass using the ``.refresh()`` method. This method reloads the python\r\nfile the class came from and replaces all methods and *class* variables\r\n(*not* instance variables!) with the versions from the new file.\r\n\r\nThe refresh is \"safe\" because it tries very hard to keep the program\r\nrunning. On each refresh, a snapshot of the class is saved to form a\r\nhistory. If an error is encountered while performing the refresh, the\r\nstate is reverted.\r\n\r\nIn general, you can wrap calls to methods of your refreshed class in a\r\ntry block that catches all errors and call ``.revert()`` on failure.\r\n\r\nAdditionally, ``DEFAULTS`` and ``AUTO_NONE`` provide options for\r\nhandling missing attributes (preventing ``AttributeError``\\ s).\r\n\r\nUsage\r\n~~~~~\r\n\r\nYou can configure the behavior by setting the following class variables:\r\n\r\n- ``STATICS`` : List of variable names (strings) that are not\r\n refreshed.\r\n- ``DEFAULTS`` : Dictionary of variable names -> values. If an\r\n ``AttributeError`` is caught, and the attribute is in ``DEFAULTS``,\r\n the attribute is populated from the dictionary. This can be useful if\r\n you need to initialize a new state variable.\r\n- ``AUTO_NONE``: If ``True``, catch ``AttributeErrors`` and set the\r\n attribute to ``None`` if the attribute is not in ``DEFAULTS``.\r\n\r\nAdditionally, there are the ``.pre_refresh()`` and ``.post_refresh()``\r\nhooks which can be overridden.\r\n\r\nOnce initialized, instances have the following methods:\r\n\r\n- ``.init_defaults()``: Initialize attributes from the ``DEFAULTS``\r\n dict.\r\n- ``.refresh()`` : Attempt to reload the class from disk.\r\n- ``.revert()`` : Revert the changes from the previous ``.refresh()``.\r\n- ``.purge()`` : Remove the state history. Each call to ``.refresh()``\r\n takes a snapshot of the class. If you refresh often w/ a big class,\r\n this can get large.\r\n\r\nLimitations\r\n~~~~~~~~~~~\r\n\r\n- ``.refresh()`` assumes all methods are bound (take a ``self``\r\n parameter). As a result, static/class methods (methods declared with\r\n ``@staticmethod``, or ``@classmethod``) will not be refreshed\r\n properly. These method names should be added to ``STATICS`` and they\r\n will not be refreshed.\r\n\r\n- This framework was designed around the singleton model with one\r\n instance of the given refreshed class. It hasn't been extensively\r\n tested with multiple instances, and may cause weird behavior around\r\n class variables.\r\n\r\n- The ``__main__`` module cannot be reloaded, so the class must exist\r\n in an imported module.\r\n\r\nrefreshable.SafeRefreshableLoop\r\n-------------------------------\r\n\r\nRun a function in a loop while making the parent class refreshable.\r\n\r\nThe function ``.step()`` is called repeatedly while the loop is running.\r\nYou can start the loop in one of two ways:\r\n\r\n- ``.start()``: Run the loop in a thread.\r\n- ``.run()`` : (the target of the thread) Run the loop \"inline\".\r\n\r\nThe loop can also be paused with ``.stop()`` and unpaused with\r\n``.restart()``.\r\n\r\nIf you subclass, make sure you call ``threading.Thread.__init__``\r\n\r\nAs with the SafeRefreshMixin, you can set the following class variables:\r\n\r\n- ``STATICS`` : List of variable names (strings) that are not\r\n refreshed.\r\n- ``DEFAULTS`` : Dictionary of variable names -> values. If an\r\n ``AttributeError`` is caught, and the attribute is in ``DEFAULTS``,\r\n the attribute is populated from the dictionary. This can be useful if\r\n you need to initialize a new state variable.\r\n- ``AUTO_NONE``: If ``True``, catch ``AttributeErrors`` and set the\r\n attribute to ``None`` if the attribute is not in ``DEFAULTS``.\r\n\r\nAnd call the following methods:\r\n\r\n- ``.refresh()``: Attempt to reload the class from disk.\r\n- ``.revert()`` : Revert the changes from the previous ``.refresh()``.\r\n- ``.purge()`` : Remove the state history. Each call to ``.refresh()``\r\n takes a snapshot of the class. If you refresh often w/ a big class,\r\n this can get large.\r\n\r\nAdditionally, there are the ``.pre_refresh()`` and ``.post_refresh()``\r\nhooks which can be overridden.\r\n\r\nTesting\r\n-------\r\n\r\n- Test it out by running ``python run_test.py`` and modifying\r\n ``test.py``.", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/zbanks/doitlive/tarball/1.0.2", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/zbanks/doitlive", "keywords": "", "license": "The MIT License (MIT)\r\n\r\nCopyright (c) 2014 Zach Banks\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\u23ce", "maintainer": "", "maintainer_email": "", "name": "refreshable", "package_url": "https://pypi.org/project/refreshable/", "platform": "", "project_url": "https://pypi.org/project/refreshable/", "project_urls": { "Download": "https://github.com/zbanks/doitlive/tarball/1.0.2", "Homepage": "https://github.com/zbanks/doitlive" }, "release_url": "https://pypi.org/project/refreshable/1.0.2/", "requires_dist": null, "requires_python": null, "summary": "Tools for livecoding performances", "version": "1.0.2" }, "last_serial": 1568857, "releases": { "1.0.1": [ { "comment_text": "", "digests": { "md5": "de0a2b2ae053b03fb307c48cb48b53d9", "sha256": "8c3c78a9a876086c19cf5f2bdce36d91894ad0eaf252592a6d31931ead2f1211" }, "downloads": -1, "filename": "refreshable-1.0.1.tar.gz", "has_sig": false, "md5_digest": "de0a2b2ae053b03fb307c48cb48b53d9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5501, "upload_time": "2015-05-28T19:58:44", "url": "https://files.pythonhosted.org/packages/09/a6/52cd1c5366e45062e1a97db02c66e6ac8272c0e5b2a8a0f3e04dba922843/refreshable-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "cd252796ccac0afdd6f7456093c53c31", "sha256": "5e1f7fa52fdd12fe0385b72254a24c9840b95afebcb335990637390f4da69b7f" }, "downloads": -1, "filename": "refreshable-1.0.2.tar.gz", "has_sig": false, "md5_digest": "cd252796ccac0afdd6f7456093c53c31", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5571, "upload_time": "2015-05-30T08:50:51", "url": "https://files.pythonhosted.org/packages/ce/30/3a4c4ff1de2817ddbac528cffb54d9003e4dae5da225ce6f2463d265b4b5/refreshable-1.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "cd252796ccac0afdd6f7456093c53c31", "sha256": "5e1f7fa52fdd12fe0385b72254a24c9840b95afebcb335990637390f4da69b7f" }, "downloads": -1, "filename": "refreshable-1.0.2.tar.gz", "has_sig": false, "md5_digest": "cd252796ccac0afdd6f7456093c53c31", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5571, "upload_time": "2015-05-30T08:50:51", "url": "https://files.pythonhosted.org/packages/ce/30/3a4c4ff1de2817ddbac528cffb54d9003e4dae5da225ce6f2463d265b4b5/refreshable-1.0.2.tar.gz" } ] }