{ "info": { "author": "Andrew Hawker", "author_email": "andrew.r.hawker@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5" ], "description": "# decorstate\n\n[![Build Status](https://travis-ci.org/ahawker/decorstate.svg?branch=master)](https://travis-ci.org/ahawker/decorstate)\n[![Test Coverage](https://codeclimate.com/github/ahawker/decorstate/badges/coverage.svg)](https://codeclimate.com/github/ahawker/decorstate/coverage)\n[![Code Climate](https://codeclimate.com/github/ahawker/decorstate/badges/gpa.svg)](https://codeclimate.com/github/ahawker/decorstate)\n[![Issue Count](https://codeclimate.com/github/ahawker/decorstate/badges/issue_count.svg)](https://codeclimate.com/github/ahawker/decorstate)\n\n[![PyPI Version](https://badge.fury.io/py/decorstate.svg)](https://badge.fury.io/py/decorstate)\n[![PyPI Versions](https://img.shields.io/pypi/pyversions/decorstate.svg)](https://pypi.python.org/pypi/decorstate)\n[![PyPI Downloads](https://img.shields.io/pypi/dm/decorstate.svg)](https://pypi.python.org/pypi/decorstate)\n\nBuild dumb little \"state machines\" with Python decorators.\n\n### Installation\n\nTo install decorstate from [pip](https://pypi.python.org/pypi/pip):\n```bash\n $ pip install decorstate\n```\n\nTo install decorstate from source:\n```bash\n $ git clone git@github.com:ahawker/decorstate.git\n $ cd decorstate\n $ python setup.py install\n```\n\n### Usage\n\nHow do I use this pile?\n\n```python\nimport decorstate\n\nclass Switch(object):\n state = 'off'\n\n @decorstate.transition('off', 'on')\n def on(self, *args, **kwargs):\n print 'You turned me on!'\n\n @decorstate.transition('on', 'off')\n def off(self, *args, **kwargs):\n print 'You turned me off!'\n\n>>> switch = Switch()\n>>> switch.state\n'off'\n>>> switch.on()\nYou turned me on!\n'on'\n>>> switch.off()\nYou turned me off!\n'off'\n```\n\nA switch? Really? How lame.\n\n\n```python\nimport decorstate\n\nclass BrokenSwitch(object):\n state = 'off'\n\n @decorstate.transition('off', 'on')\n def on(self, *args, **kwargs):\n print 'You turned me on!'\n\n @decorstate.transition('on', 'off')\n def off(self, *args, **kwargs):\n print 'You turned me off? Nah!'\n\n @off.guard\n def off(self, *args, **kwargs):\n print 'Ha! I laugh at your feeble attempt!'\n\n>>> broken_switch = BrokenSwitch()\n>>> broken_switch.state\n'off'\n>>> broken_switch.on()\nYou turned me on!\n'on'\n>>> broken_switch.off()\nHa! I laugh at your feeble attempt!\n'on'\n>>> broken_switch.state\n'on'\n>>> broken_switch.off()\nHa! I laugh at your feeble attempt!\n'on'\n>>> broken_switch.state\n'on'\n```\n\nA broken switch? Yawn.\n\n\n```python\nimport decorstate\n\nclass InstantOffSwitch(object):\n state = 'off'\n\n @decorstate.transition('off', 'off')\n def on(self, *args, **kwargs):\n print 'You turned me on!'\n\n @decorstate.transition('on', 'off')\n def off(self, *args, **kwargs):\n print 'You turned me off!'\n\n @on.after\n def on(self, *args, **kwargs):\n print 'Ha! No light for you!'\n\n>>> instant_off_switch = InstantOffSwitch()\n>>> instant_off_switch.state\n'off'\n>>> instant_off_switch.on()\nYou turned me on!\nHa! No light for you!\n'off'\n>>> instant_off_switch.state\n'off'\n```\n\nWell, that's kinda mean.\n\n\n```python\nimport decorstate\nimport random\n\nclass IoTSwitch(object):\n state = 'off'\n\n @decorstate.transition('off', 'off')\n def on(self, *args, **kwargs):\n print 'You turned me on? Maybe...'\n\n @decorstate.transition('on', 'off')\n def off(self, *args, **kwargs):\n print 'You turned me off? Maybe...'\n\n @on.guard\n def on(self, *args, **kwargs):\n return self.coin_flip()\n\n @off.guard\n def off(self, *args, **kwargs):\n return not self.coin_flip()\n\n @staticmethod\n def coin_flip():\n return random.randint(1, 2) == 1\n\n>>> iot_switch = IoTSwitch()\n>>> iot_switch.state\n'off'\n>>> iot_switch.on()\n'off'\n>>> iot_switch.on()\n'off'\n>>> iot_switch.on()\n'off'\n>>> iot_switch.on()\nYou turned me on? Maybe...\n'on'\n>>> iot_switch.off()\n'on'\n>>> iot_switch.off()\n'on'\n>>> iot_switch.off()\n'on'\n>>> iot_switch.off()\n'on'\n>>> iot_switch.off()\nYou turned me off? Maybe...\n'off'\n```\n\nHey now, why you hating? Internet powered light switches are next level shit. My living room has its own twitter feed.\n\n\n### Why?\n\nI was interesting in doing something a bit more complex using the Python [descriptor protocol](https://docs.python.org/2/howto/descriptor.html).\n\n### TODO?\n\nRandom thoughts and musing about potential changes/features.\n\n* Consider adding the @machine decorator back as currently, you cannot use the \"state\", \"transition\" and \"transition_event\" attributes until the first transition has been performed since they are lazy created.\n* Add event handler that fires only when \"entering\" a state and not when you perform multiple transitions but stay in the same state.\n\n### License\n\n[Apache 2.0](LICENSE)", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ahawker/decorstate", "keywords": "", "license": "Apache 2.0", "maintainer": "", "maintainer_email": "", "name": "decorstate", "package_url": "https://pypi.org/project/decorstate/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/decorstate/", "project_urls": { "Homepage": "https://github.com/ahawker/decorstate" }, "release_url": "https://pypi.org/project/decorstate/0.0.3/", "requires_dist": null, "requires_python": "", "summary": "Simple \"state machines\" with Python decorators", "version": "0.0.3" }, "last_serial": 2934277, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "0c7f544878ecf5fe3330b92c347880b3", "sha256": "dd4b66c76fc84655432cb068a9daea571725c3d864aa9b065379896714b87990" }, "downloads": -1, "filename": "decorstate-0.0.1-py2.7.egg", "has_sig": false, "md5_digest": "0c7f544878ecf5fe3330b92c347880b3", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 8981, "upload_time": "2015-12-22T08:51:54", "url": "https://files.pythonhosted.org/packages/3c/51/e1a79803978363f364f145ee7f5492b598cde12c496d48904a75240aafc9/decorstate-0.0.1-py2.7.egg" } ], "0.0.2": [], "0.0.3": [ { "comment_text": "", "digests": { "md5": "69314806fbd71131449cd39c0ac773eb", "sha256": "2b10af7eb77c14cb863786355e11ebe2c6e4030407bd9fb0b8c5ea2747df1e0e" }, "downloads": -1, "filename": "decorstate-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "69314806fbd71131449cd39c0ac773eb", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11800, "upload_time": "2017-06-08T03:24:23", "url": "https://files.pythonhosted.org/packages/62/c5/62632f1de0c317911fb5e5d32a0f1c5b3b049f6fbc2cf20ebd332e60bac7/decorstate-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fca48f57cc566de712dc3c54743911f1", "sha256": "285fe86bafd8f99a021926c5083c893e586ba81ba8380d960001d4ec61ed88ba" }, "downloads": -1, "filename": "decorstate-0.0.3.tar.gz", "has_sig": false, "md5_digest": "fca48f57cc566de712dc3c54743911f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5675, "upload_time": "2017-06-08T03:24:25", "url": "https://files.pythonhosted.org/packages/67/30/7ca32fb3b6474e344dc33b53c9a07034514cea1c286c88e4386cc8175194/decorstate-0.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "69314806fbd71131449cd39c0ac773eb", "sha256": "2b10af7eb77c14cb863786355e11ebe2c6e4030407bd9fb0b8c5ea2747df1e0e" }, "downloads": -1, "filename": "decorstate-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "69314806fbd71131449cd39c0ac773eb", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11800, "upload_time": "2017-06-08T03:24:23", "url": "https://files.pythonhosted.org/packages/62/c5/62632f1de0c317911fb5e5d32a0f1c5b3b049f6fbc2cf20ebd332e60bac7/decorstate-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fca48f57cc566de712dc3c54743911f1", "sha256": "285fe86bafd8f99a021926c5083c893e586ba81ba8380d960001d4ec61ed88ba" }, "downloads": -1, "filename": "decorstate-0.0.3.tar.gz", "has_sig": false, "md5_digest": "fca48f57cc566de712dc3c54743911f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5675, "upload_time": "2017-06-08T03:24:25", "url": "https://files.pythonhosted.org/packages/67/30/7ca32fb3b6474e344dc33b53c9a07034514cea1c286c88e4386cc8175194/decorstate-0.0.3.tar.gz" } ] }