State¶
The descriptor that holds a machine's current state, and the namespace for the transition decorator and its target helpers.
State(states, default=None)¶
| Argument | Type | Default | Notes |
|---|---|---|---|
states |
anything | — | Required. Documentation only — it is not stored or validated against |
default |
any state value | None |
The state reported before any transition |
Omitting states is a TypeError, even though the value is unused:
>>> State(default='todo')
Traceback (most recent call last):
...
TypeError: State.__init__() missing 1 required positional argument: 'states'
Attributes¶
| Name | Description |
|---|---|
State.ANY |
Wildcard source, matched when no exact source is registered |
propname |
The instance attribute the value is stored under, '__fsm_' + name |
Descriptor behaviour¶
| Access | Result |
|---|---|
instance.state |
The current state value, via get() |
Cls.state |
A StateDescriptor — see Transitions |
instance.state = value |
Always raises AttributeError |
>>> task = Task()
>>> task.status = 'done'
Traceback (most recent call last):
...
AttributeError: Direct state modification is not allowed
Methods¶
get(instance)¶
Returns the current state. With a @state.getter() installed, the getter's
value is used, falling back to default when it is None or '' and
default is truthy. Without a getter, reads instance.__fsm_<name>, defaulting
to default.
See The empty-value rule.
set(instance, value)¶
Writes the state, through the @state.setter() if one is installed. Called by
the transition machinery; calling it yourself bypasses the machine.
transition_succeed(instance, transition, source, target, **kwargs)¶
Invokes the @state.on_success() hook, if one is installed. Called after a
transition commits.
Decorators¶
transition(source, target=DEFAULT, label=None, conditions=None, custom=None)¶
Registers a method as a transition. See Transitions.
| Argument | Notes |
|---|---|
source |
One state, or a list/tuple/set of them, or State.ANY |
target |
Omit for no state change. None raises ValueError |
label |
Falls back to func.__name__.title() |
conditions |
A sequence of callables taking the instance |
custom |
A dict, stored on the transition and never read by the library |
super()¶
Wraps an inherited transition, reusing its source and target. Raises
ValueError('Base transition not found') if no base declares a transition
method of that name. See
Inheritance.
getter() / setter() / on_success()¶
Install the accessors and the commit hook. See Binding state to storage.
>>> class Stored:
... state = State(['new', 'done'], default='new')
... def __init__(self, row):
... self.row = row
... @state.getter()
... def _read(self):
... return self.row['state']
... @state.setter()
... def _write(self, value):
... self.row['state'] = value
... @state.on_success()
... def _save(self, transition, source, target, **kwargs):
... self.row['saved'] = True
... @state.transition(source='new', target='done')
... def finish(self):
... """Finish the job."""
>>> row = {'state': ''}
>>> stored = Stored(row)
>>> stored.state
'new'
>>> stored.finish()
>>> row
{'state': 'done', 'saved': True}
The on_success signature is
(self, transition, source, target, **kwargs), where kwargs are the keyword
arguments the caller passed to the transition.
State.CONDITION(is_true, unmet='')¶
A boolean-like result carrying the reason a condition refused.
| Member | Description |
|---|---|
is_true |
The boolean result |
unmet |
The message, as passed |
message |
unmet when it refused, '' when it passed |
__bool__ |
is_true |
>>> State.CONDITION(False, unmet='too short').message
'too short'
>>> State.CONDITION(True, unmet='too short').message
''
See Conditions.
State.RETURN_VALUE(*allowed_states)¶
A target resolved from the transition method's return value, after the body
runs. Stores allowed_states as a tuple; empty means any value is accepted.
Raises InvalidTargetState otherwise.
State.GET_STATE(func, states=None)¶
A target computed by func(instance, *args, **kwargs), before the body runs.
Stores states as a list, defaulting to [], which means any value is
accepted. Raises InvalidTargetState otherwise.
Both are covered in full in Dynamic targets.
Related pages¶
- The State field — the guide
- Transitions reference — what the decorator produces
- Errors — every exception