===================
Super State Machine
===================
.. image:: https://badge.fury.io/py/super_state_machine.png
:target: http://badge.fury.io/py/super_state_machine
.. image:: https://travis-ci.org/beregond/super_state_machine.png?branch=master
:target: https://travis-ci.org/beregond/super_state_machine
.. image:: https://pypip.in/d/super_state_machine/badge.png
:target: https://pypi.python.org/pypi/super_state_machine
Super State Machine gives you utilities to build finite state machines.
* Free software: BSD license
* Documentation: https://super_state_machine.readthedocs.org
* Source: https://github.com/beregond/super_state_machine
Features
--------
* Fully tested with Python 2.7, 3.3, 3.4 and PyPy.
* Create finite state machines:
.. code-block:: python
>>> from enum import Enum
>>> from super_state_machine import machines
>>> class Task(machines.StateMachine):
...
... state = 'draft'
...
... class States(Enum):
...
... DRAFT = 'draft'
... SCHEDULED = 'scheduled'
... PROCESSING = 'processing'
... SENT = 'sent'
... FAILED = 'failed'
>>> task = Task()
>>> task.is_draft
False
>>> task.set_draft()
>>> task.state
'draft'
>>> task.state = 'scheduled'
>>> task.is_scheduled
True
>>> task.state = 'process'
>>> task.state
'processing'
>>> task.state = 'wrong'
*** ValueError: Unrecognized value ('wrong').
* Define allowed transitions graph, define additional named transitions
and checkers:
.. code-block:: python
>>> class Task(machines.StateMachine):
...
... class States(Enum):
...
... DRAFT = 'draft'
... SCHEDULED = 'scheduled'
... PROCESSING = 'processing'
... SENT = 'sent'
... FAILED = 'failed'
...
... class Meta:
...
... allow_empty = False
... initial_state = 'draft'
... transitions = {
... 'draft': ['scheduled', 'failed'],
... 'scheduled': ['failed'],
... 'processing': ['sent', 'failed']
... }
... named_transitions = [
... ('process', 'processing', ['scheduled']),
... ('fail', 'failed')
... ]
... named_checkers = [
... ('can_be_processed', 'processing'),
... ]
>>> task = Task()
>>> task.state
'draft'
>>> task.process()
*** TransitionError: Cannot transit from 'draft' to 'processing'.
>>> task.set_scheduled()
>>> task.can_be_processed
True
>>> task.process()
>>> task.state
'processing'
>>> task.fail()
>>> task.state
'failed'
Note, that third argument restricts from which states transition will be
**added** to allowed (in case of ``process``, new allowed transition will be
added, from 'scheduled' to 'processing'). No argument means all available
states, ``None`` or empty list won't add anything beyond defined ones.
* Use state machines as properties:
.. code-block:: python
>>> from enum import Enum
>>> from super_state_machine import machines, extras
>>> class Lock(machine.StateMachine):
... class States(Enum):
...
... OPEN = 'open'
... LOCKED = 'locked'
...
... class Meta:
...
... allow_empty = False
... initial_state = 'locked'
... named_transitions = [
... ('open', 'open'),
... ('lock', 'locked'),
... ]
>>> class Safe(object):
...
... lock1 = extras.PropertyMachine(Lock)
... lock2 = extras.PropertyMachine(Lock)
... lock3 = extras.PropertyMachine(Lock)
...
... locks = ['lock1', 'lock2', 'lock3']
...
... def is_locked(self):
... locks = [getattr(self, lock).is_locked for lock in self.locks]
... return any(locks)
...
... def is_open(self):
... locks = [getattr(self, lock).is_open for lock in self.locks]
... return all(locks)
>>> safe = Safe()
>>> safe.lock1
'locked'
>>> safe.is_open
False
>>> safe.lock1.open()
>>> safe.lock1.is_open
True
>>> safe.lock1
'open'
>>> safe.is_open
False
>>> safe.lock2.open()
>>> safe.lock3 = 'open'
>>> safe.is_open
True
History
-------
2.0.2 (2017-03-13)
++++++++++++++++++
* Fixed requirements for Python > 3.4.
2.0.1 (2017-02-27)
++++++++++++++++++
* Remove enum34 for Python > 3.4.
* Added support for Python 2.6.
2.0 (2016-09-26)
++++++++++++++++
* Added force_set method.
* Added field machine.
* Added support for Python 3.5.
Backward compatibility breaks:
* Empty state is now disallowed.
* Only full names are allowed, when using scalars, no shortcuts.
* Removed support for unhashable types.
1.0 (2014-09-04)
----------------
* Added all basic features.
0.1.0 (2014-08-08)
---------------------
* First release on PyPI.
* Added utilities to create simple state machine.
Raw data
{
"_id": null,
"home_page": "https://github.com/beregond/super_state_machine",
"name": "super_state_machine",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "super_state_machine",
"author": "Szczepan Cie\u015blik",
"author_email": "szczepan.cieslik@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/84/ee/2c55720ce1c35e00299e57e673945c5d6379f5fc1cbe9e7d0405ca11cc72/super_state_machine-2.0.2.tar.gz",
"platform": "",
"description": "===================\nSuper State Machine\n===================\n\n.. image:: https://badge.fury.io/py/super_state_machine.png\n :target: http://badge.fury.io/py/super_state_machine\n\n.. image:: https://travis-ci.org/beregond/super_state_machine.png?branch=master\n :target: https://travis-ci.org/beregond/super_state_machine\n\n.. image:: https://pypip.in/d/super_state_machine/badge.png\n :target: https://pypi.python.org/pypi/super_state_machine\n\n\nSuper State Machine gives you utilities to build finite state machines.\n\n* Free software: BSD license\n* Documentation: https://super_state_machine.readthedocs.org\n* Source: https://github.com/beregond/super_state_machine\n\nFeatures\n--------\n\n* Fully tested with Python 2.7, 3.3, 3.4 and PyPy.\n\n* Create finite state machines:\n\n .. code-block:: python\n\n >>> from enum import Enum\n\n >>> from super_state_machine import machines\n\n\n >>> class Task(machines.StateMachine):\n ...\n ... state = 'draft'\n ...\n ... class States(Enum):\n ...\n ... DRAFT = 'draft'\n ... SCHEDULED = 'scheduled'\n ... PROCESSING = 'processing'\n ... SENT = 'sent'\n ... FAILED = 'failed'\n\n >>> task = Task()\n >>> task.is_draft\n False\n >>> task.set_draft()\n >>> task.state\n 'draft'\n >>> task.state = 'scheduled'\n >>> task.is_scheduled\n True\n >>> task.state = 'process'\n >>> task.state\n 'processing'\n >>> task.state = 'wrong'\n *** ValueError: Unrecognized value ('wrong').\n\n* Define allowed transitions graph, define additional named transitions\n and checkers:\n\n .. code-block:: python\n\n >>> class Task(machines.StateMachine):\n ...\n ... class States(Enum):\n ...\n ... DRAFT = 'draft'\n ... SCHEDULED = 'scheduled'\n ... PROCESSING = 'processing'\n ... SENT = 'sent'\n ... FAILED = 'failed'\n ...\n ... class Meta:\n ...\n ... allow_empty = False\n ... initial_state = 'draft'\n ... transitions = {\n ... 'draft': ['scheduled', 'failed'],\n ... 'scheduled': ['failed'],\n ... 'processing': ['sent', 'failed']\n ... }\n ... named_transitions = [\n ... ('process', 'processing', ['scheduled']),\n ... ('fail', 'failed')\n ... ]\n ... named_checkers = [\n ... ('can_be_processed', 'processing'),\n ... ]\n\n >>> task = Task()\n >>> task.state\n 'draft'\n >>> task.process()\n *** TransitionError: Cannot transit from 'draft' to 'processing'.\n >>> task.set_scheduled()\n >>> task.can_be_processed\n True\n >>> task.process()\n >>> task.state\n 'processing'\n >>> task.fail()\n >>> task.state\n 'failed'\n\n Note, that third argument restricts from which states transition will be\n **added** to allowed (in case of ``process``, new allowed transition will be\n added, from 'scheduled' to 'processing'). No argument means all available\n states, ``None`` or empty list won't add anything beyond defined ones.\n\n* Use state machines as properties:\n\n.. code-block:: python\n\n >>> from enum import Enum\n\n >>> from super_state_machine import machines, extras\n\n\n >>> class Lock(machine.StateMachine):\n\n ... class States(Enum):\n ...\n ... OPEN = 'open'\n ... LOCKED = 'locked'\n ...\n ... class Meta:\n ...\n ... allow_empty = False\n ... initial_state = 'locked'\n ... named_transitions = [\n ... ('open', 'open'),\n ... ('lock', 'locked'),\n ... ]\n\n\n >>> class Safe(object):\n ...\n ... lock1 = extras.PropertyMachine(Lock)\n ... lock2 = extras.PropertyMachine(Lock)\n ... lock3 = extras.PropertyMachine(Lock)\n ...\n ... locks = ['lock1', 'lock2', 'lock3']\n ...\n ... def is_locked(self):\n ... locks = [getattr(self, lock).is_locked for lock in self.locks]\n ... return any(locks)\n ...\n ... def is_open(self):\n ... locks = [getattr(self, lock).is_open for lock in self.locks]\n ... return all(locks)\n\n >>> safe = Safe()\n >>> safe.lock1\n 'locked'\n >>> safe.is_open\n False\n >>> safe.lock1.open()\n >>> safe.lock1.is_open\n True\n >>> safe.lock1\n 'open'\n >>> safe.is_open\n False\n >>> safe.lock2.open()\n >>> safe.lock3 = 'open'\n >>> safe.is_open\n True\n\n\n\n\nHistory\n-------\n\n2.0.2 (2017-03-13)\n++++++++++++++++++\n\n* Fixed requirements for Python > 3.4.\n\n2.0.1 (2017-02-27)\n++++++++++++++++++\n\n* Remove enum34 for Python > 3.4.\n* Added support for Python 2.6.\n\n\n2.0 (2016-09-26)\n++++++++++++++++\n\n* Added force_set method.\n* Added field machine.\n* Added support for Python 3.5.\n\nBackward compatibility breaks:\n\n* Empty state is now disallowed.\n* Only full names are allowed, when using scalars, no shortcuts.\n* Removed support for unhashable types.\n\n1.0 (2014-09-04)\n----------------\n\n* Added all basic features.\n\n0.1.0 (2014-08-08)\n---------------------\n\n* First release on PyPI.\n* Added utilities to create simple state machine.\n\n\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "Super State Machine gives you utilities to build finite state machines.",
"version": "2.0.2",
"split_keywords": [
"super_state_machine"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "f0e60be7403d98115646b818628fadbe",
"sha256": "6f615d55970be4ab57f5121a15b60568145effa49e9316a2eaaf51b0b81f3456"
},
"downloads": -1,
"filename": "super_state_machine-2.0.2-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "f0e60be7403d98115646b818628fadbe",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 10275,
"upload_time": "2017-03-13T15:35:15",
"upload_time_iso_8601": "2017-03-13T15:35:15.982040Z",
"url": "https://files.pythonhosted.org/packages/5a/c0/0d5a60657096284b81b70f9a8e3a75de7e433f45b3c5ad17fbd312f15f59/super_state_machine-2.0.2-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "296e32ba7c2ca34e4e4cf0e8715f3bc4",
"sha256": "e038a4c573ab80f157bf726c3036367919704f62cd166eb46837143165035958"
},
"downloads": -1,
"filename": "super_state_machine-2.0.2.tar.gz",
"has_sig": false,
"md5_digest": "296e32ba7c2ca34e4e4cf0e8715f3bc4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 24423,
"upload_time": "2017-03-13T15:35:17",
"upload_time_iso_8601": "2017-03-13T15:35:17.765468Z",
"url": "https://files.pythonhosted.org/packages/84/ee/2c55720ce1c35e00299e57e673945c5d6379f5fc1cbe9e7d0405ca11cc72/super_state_machine-2.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2017-03-13 15:35:17",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "beregond",
"github_project": "super_state_machine",
"travis_ci": true,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "Jinja2",
"specs": [
[
"==",
"2.7.3"
]
]
},
{
"name": "MarkupSafe",
"specs": [
[
"==",
"0.23"
]
]
},
{
"name": "Pygments",
"specs": [
[
"==",
"1.6"
]
]
},
{
"name": "Sphinx",
"specs": [
[
"==",
"1.2.2"
]
]
},
{
"name": "docutils",
"specs": [
[
"==",
"0.12"
]
]
},
{
"name": "flake8",
"specs": [
[
"==",
"2.2.2"
]
]
},
{
"name": "mccabe",
"specs": [
[
"==",
"0.2.1"
]
]
},
{
"name": "pep8",
"specs": [
[
"==",
"1.5.7"
]
]
},
{
"name": "py",
"specs": [
[
"==",
"1.4.31"
]
]
},
{
"name": "pyflakes",
"specs": [
[
"==",
"0.8.1"
]
]
},
{
"name": "pytest",
"specs": [
[
"==",
"3.0.2"
]
]
},
{
"name": "pytest-cov",
"specs": [
[
"==",
"2.3.1"
]
]
},
{
"name": "pyhistory",
"specs": [
[
"==",
"1.2.1"
]
]
},
{
"name": "tox",
"specs": [
[
"==",
"1.7.2"
]
]
},
{
"name": "virtualenv",
"specs": [
[
"==",
"1.11.6"
]
]
},
{
"name": "wheel",
"specs": [
[
"==",
"0.23.0"
]
]
}
],
"tox": true,
"lcname": "super_state_machine"
}