WIP add docstrings to persist
This commit is contained in:
parent
dbb2280a03
commit
5cc0af80d6
@ -4,6 +4,15 @@ from .error import StateItemExists
|
|||||||
|
|
||||||
|
|
||||||
class PersistedState(State):
|
class PersistedState(State):
|
||||||
|
"""Adapter for persisting state changes and synchronising states between memory and persisted backend.
|
||||||
|
|
||||||
|
:param factory: A function capable of returning a persisted store from a single path argument.
|
||||||
|
:type factory: function
|
||||||
|
:param bits: Number of pure states. Passed to the superclass.
|
||||||
|
:type bits: int
|
||||||
|
:param logger: Logger to capture logging output, or None for no logging.
|
||||||
|
:type logger: object
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, factory, bits, logger=None):
|
def __init__(self, factory, bits, logger=None):
|
||||||
super(PersistedState, self).__init__(bits, logger=logger)
|
super(PersistedState, self).__init__(bits, logger=logger)
|
||||||
@ -11,12 +20,17 @@ class PersistedState(State):
|
|||||||
self.__stores = {}
|
self.__stores = {}
|
||||||
|
|
||||||
|
|
||||||
|
# Create state store container if missing.
|
||||||
def __ensure_store(self, k):
|
def __ensure_store(self, k):
|
||||||
if self.__stores.get(k) == None:
|
if self.__stores.get(k) == None:
|
||||||
self.__stores[k] = self.__store_factory(k)
|
self.__stores[k] = self.__store_factory(k)
|
||||||
|
|
||||||
|
|
||||||
def put(self, key, contents=None, state=None):
|
def put(self, key, contents=None, state=None):
|
||||||
|
"""Persist a key or key/content pair.
|
||||||
|
|
||||||
|
See shep.state.State.put
|
||||||
|
"""
|
||||||
to_state = super(PersistedState, self).put(key, state=state, contents=contents)
|
to_state = super(PersistedState, self).put(key, state=state, contents=contents)
|
||||||
|
|
||||||
k = self.name(to_state)
|
k = self.name(to_state)
|
||||||
@ -26,6 +40,10 @@ class PersistedState(State):
|
|||||||
|
|
||||||
|
|
||||||
def set(self, key, or_state):
|
def set(self, key, or_state):
|
||||||
|
"""Persist a new state for a key or key/content.
|
||||||
|
|
||||||
|
See shep.state.State.set
|
||||||
|
"""
|
||||||
from_state = self.state(key)
|
from_state = self.state(key)
|
||||||
k_from = self.name(from_state)
|
k_from = self.name(from_state)
|
||||||
|
|
||||||
@ -41,6 +59,10 @@ class PersistedState(State):
|
|||||||
|
|
||||||
|
|
||||||
def unset(self, key, not_state):
|
def unset(self, key, not_state):
|
||||||
|
"""Persist a new state for a key or key/content.
|
||||||
|
|
||||||
|
See shep.state.State.unset
|
||||||
|
"""
|
||||||
from_state = self.state(key)
|
from_state = self.state(key)
|
||||||
k_from = self.name(from_state)
|
k_from = self.name(from_state)
|
||||||
|
|
||||||
@ -57,11 +79,16 @@ class PersistedState(State):
|
|||||||
|
|
||||||
|
|
||||||
def move(self, key, to_state):
|
def move(self, key, to_state):
|
||||||
|
"""Persist a new state for a key or key/content.
|
||||||
|
|
||||||
|
See shep.state.State.move
|
||||||
|
"""
|
||||||
from_state = self.state(key)
|
from_state = self.state(key)
|
||||||
to_state = super(PersistedState, self).move(key, to_state)
|
to_state = super(PersistedState, self).move(key, to_state)
|
||||||
return self.__movestore(key, from_state, to_state)
|
return self.__movestore(key, from_state, to_state)
|
||||||
|
|
||||||
|
|
||||||
|
# common procedure for safely moving a persisted resource from one state to another.
|
||||||
def __movestore(self, key, from_state, to_state):
|
def __movestore(self, key, from_state, to_state):
|
||||||
k_from = self.name(from_state)
|
k_from = self.name(from_state)
|
||||||
k_to = self.name(to_state)
|
k_to = self.name(to_state)
|
||||||
@ -76,6 +103,13 @@ class PersistedState(State):
|
|||||||
|
|
||||||
|
|
||||||
def sync(self, state):
|
def sync(self, state):
|
||||||
|
"""Reload resources for a single state in memory from the persisted state store.
|
||||||
|
|
||||||
|
:param state: State to load
|
||||||
|
:type state: int
|
||||||
|
:raises StateItemExists: A content key is already recorded with a different state in memory than in persisted store.
|
||||||
|
# :todo: if sync state is none, sync all
|
||||||
|
"""
|
||||||
k = self.name(state)
|
k = self.name(state)
|
||||||
|
|
||||||
self.__ensure_store(k)
|
self.__ensure_store(k)
|
||||||
@ -89,36 +123,51 @@ class PersistedState(State):
|
|||||||
|
|
||||||
|
|
||||||
def list(self, state):
|
def list(self, state):
|
||||||
|
"""List all content keys for a particular state.
|
||||||
|
|
||||||
|
This method will return from memory, and will not sync the persisted state first.
|
||||||
|
|
||||||
|
See shep.state.State.list
|
||||||
|
"""
|
||||||
k = self.name(state)
|
k = self.name(state)
|
||||||
self.__ensure_store(k)
|
self.__ensure_store(k)
|
||||||
#return self.__stores[k].list(state)
|
#return self.__stores[k].list(state)
|
||||||
return super(PersistedState, self).list(state)
|
return super(PersistedState, self).list(state)
|
||||||
|
|
||||||
|
|
||||||
# Return a file path or URL pointing to the persisted state.
|
|
||||||
#
|
|
||||||
# If the key is omitted, the URL to the state item's container must be returned, and None if no such container exists.
|
|
||||||
#
|
|
||||||
# :param state: State to locate
|
|
||||||
# :type state: int
|
|
||||||
# :param key: Content key to locate
|
|
||||||
# :type key: str
|
|
||||||
# :rtype: str
|
|
||||||
# :returns: Locator pointng to persisted state
|
|
||||||
# :todo: rename to "location"
|
|
||||||
def path(self, state, key=None):
|
def path(self, state, key=None):
|
||||||
|
"""Return a file path or URL pointing to the persisted state.
|
||||||
|
|
||||||
|
If the key is omitted, the URL to the state item's container must be returned, and None if no such container exists.
|
||||||
|
|
||||||
|
:param state: State to locate
|
||||||
|
:type state: int
|
||||||
|
:param key: Content key to locate
|
||||||
|
:type key: str
|
||||||
|
:rtype: str
|
||||||
|
:returns: Locator pointng to persisted state
|
||||||
|
:todo: rename to "location"
|
||||||
|
"""
|
||||||
k = self.name(state)
|
k = self.name(state)
|
||||||
self.__ensure_store(k)
|
self.__ensure_store(k)
|
||||||
return self.__stores[k].path(key=key)
|
return self.__stores[k].path(key=key)
|
||||||
|
|
||||||
|
|
||||||
def next(self, key=None):
|
def next(self, key=None):
|
||||||
|
"""Advance and persist to the next pure state.
|
||||||
|
|
||||||
|
See shep.state.State.next
|
||||||
|
"""
|
||||||
from_state = self.state(key)
|
from_state = self.state(key)
|
||||||
to_state = super(PersistedState, self).next(key)
|
to_state = super(PersistedState, self).next(key)
|
||||||
return self.__movestore(key, from_state, to_state)
|
return self.__movestore(key, from_state, to_state)
|
||||||
|
|
||||||
|
|
||||||
def replace(self, key, contents):
|
def replace(self, key, contents):
|
||||||
|
"""Replace contents associated by content key.
|
||||||
|
|
||||||
|
See shep.state.State.replace
|
||||||
|
"""
|
||||||
super(PersistedState, self).replace(key, contents)
|
super(PersistedState, self).replace(key, contents)
|
||||||
state = self.state(key)
|
state = self.state(key)
|
||||||
k = self.name(state)
|
k = self.name(state)
|
||||||
|
319
shep/state.py
319
shep/state.py
@ -118,10 +118,11 @@ class State:
|
|||||||
self.__keys_reverse[item] = state
|
self.__keys_reverse[item] = state
|
||||||
|
|
||||||
|
|
||||||
# Get index of a key for a given state.
|
|
||||||
# A key should only ever exist in one state.
|
|
||||||
# A failed lookup should indicate a mistake on the caller part, (it may also indicate corruption, but probanbly impossible to tell the difference)
|
|
||||||
def __state_list_index(self, item, state_list):
|
def __state_list_index(self, item, state_list):
|
||||||
|
"""Get index of a key for a given state.
|
||||||
|
A key should only ever exist in one state.
|
||||||
|
A failed lookup should indicate a mistake on the caller part, (it may also indicate corruption, but probanbly impossible to tell the difference)
|
||||||
|
"""
|
||||||
idx = -1
|
idx = -1
|
||||||
try:
|
try:
|
||||||
idx = state_list.index(item)
|
idx = state_list.index(item)
|
||||||
@ -134,29 +135,31 @@ class State:
|
|||||||
return idx
|
return idx
|
||||||
|
|
||||||
|
|
||||||
# Add a state to the store.
|
|
||||||
#
|
|
||||||
# :param k: State name
|
|
||||||
# :type k: str
|
|
||||||
# :raises shep.error.StateExists: State name is already registered
|
|
||||||
def add(self, k):
|
def add(self, k):
|
||||||
|
"""Add a state to the store.
|
||||||
|
|
||||||
|
:param k: State name
|
||||||
|
:type k: str
|
||||||
|
:raises shep.error.StateExists: State name is already registered
|
||||||
|
"""
|
||||||
v = 1 << self.__c
|
v = 1 << self.__c
|
||||||
k = self.__check_name(k)
|
k = self.__check_name(k)
|
||||||
v = self.__check_value(v)
|
v = self.__check_value(v)
|
||||||
self.__set(k, v)
|
self.__set(k, v)
|
||||||
|
|
||||||
|
|
||||||
# Add an alias for a combination of states in the store.
|
|
||||||
#
|
|
||||||
# State aggregates may be provided as comma separated values or as a single (or'd) integer value.
|
|
||||||
#|
|
|
||||||
# :param k: Alias name
|
|
||||||
# :type k: str
|
|
||||||
# :param *args: One or more states to aggregate for this alias.
|
|
||||||
# :type *args: int or list of ints
|
|
||||||
# :raises StateInvalid: Attempt to create alias for one or more atomic states that do not exist.
|
|
||||||
# :raises ValueError: Attempt to use bit value as alias
|
|
||||||
def alias(self, k, *args):
|
def alias(self, k, *args):
|
||||||
|
"""Add an alias for a combination of states in the store.
|
||||||
|
|
||||||
|
State aggregates may be provided as comma separated values or as a single (or'd) integer value.
|
||||||
|
|
||||||
|
:param k: Alias name
|
||||||
|
:type k: str
|
||||||
|
:param *args: One or more states to aggregate for this alias.
|
||||||
|
:type *args: int or list of ints
|
||||||
|
:raises StateInvalid: Attempt to create alias for one or more atomic states that do not exist.
|
||||||
|
:raises ValueError: Attempt to use bit value as alias
|
||||||
|
"""
|
||||||
k = self.__check_name(k)
|
k = self.__check_name(k)
|
||||||
v = 0
|
v = 0
|
||||||
for a in args:
|
for a in args:
|
||||||
@ -167,11 +170,12 @@ class State:
|
|||||||
self.__set(k, v)
|
self.__set(k, v)
|
||||||
|
|
||||||
|
|
||||||
# Return list of all unique atomic and alias states.
|
|
||||||
#
|
|
||||||
# :rtype: list of ints
|
|
||||||
# :return: states
|
|
||||||
def all(self):
|
def all(self):
|
||||||
|
"""Return list of all unique atomic and alias states.
|
||||||
|
|
||||||
|
:rtype: list of ints
|
||||||
|
:return: states
|
||||||
|
"""
|
||||||
l = []
|
l = []
|
||||||
for k in dir(self):
|
for k in dir(self):
|
||||||
if k[0] == '_':
|
if k[0] == '_':
|
||||||
@ -183,14 +187,15 @@ class State:
|
|||||||
return l
|
return l
|
||||||
|
|
||||||
|
|
||||||
# Retrieve that string representation of the state attribute represented by the given state integer value.
|
|
||||||
#
|
|
||||||
# :param v: State integer
|
|
||||||
# :type v: int
|
|
||||||
# :raises StateInvalid: State corresponding to given integer not found
|
|
||||||
# :rtype: str
|
|
||||||
# :return: State name
|
|
||||||
def name(self, v):
|
def name(self, v):
|
||||||
|
"""Retrieve that string representation of the state attribute represented by the given state integer value.
|
||||||
|
|
||||||
|
:param v: State integer
|
||||||
|
:type v: int
|
||||||
|
:raises StateInvalid: State corresponding to given integer not found
|
||||||
|
:rtype: str
|
||||||
|
:return: State name
|
||||||
|
"""
|
||||||
if v == None or v == 0:
|
if v == None or v == 0:
|
||||||
return 'NEW'
|
return 'NEW'
|
||||||
k = self.__reverse.get(v)
|
k = self.__reverse.get(v)
|
||||||
@ -199,31 +204,33 @@ class State:
|
|||||||
return k
|
return k
|
||||||
|
|
||||||
|
|
||||||
# Retrieve the real state integer value corresponding to an attribute name.
|
|
||||||
#
|
|
||||||
# :param k: Attribute name
|
|
||||||
# :type k: str
|
|
||||||
# :raises ValueError: Invalid attribute name
|
|
||||||
# :raises AttributeError: Attribute not found
|
|
||||||
# :rtype: int
|
|
||||||
# :return: Numeric state value
|
|
||||||
def from_name(self, k):
|
def from_name(self, k):
|
||||||
|
"""Retrieve the real state integer value corresponding to an attribute name.
|
||||||
|
|
||||||
|
:param k: Attribute name
|
||||||
|
:type k: str
|
||||||
|
:raises ValueError: Invalid attribute name
|
||||||
|
:raises AttributeError: Attribute not found
|
||||||
|
:rtype: int
|
||||||
|
:return: Numeric state value
|
||||||
|
"""
|
||||||
k = self.__check_name_valid(k)
|
k = self.__check_name_valid(k)
|
||||||
return getattr(self, k)
|
return getattr(self, k)
|
||||||
|
|
||||||
|
|
||||||
# Match against all stored states.
|
|
||||||
#
|
|
||||||
# If pure is set, only match against the single atomic state will be returned.
|
|
||||||
#
|
|
||||||
# :param v: Integer state to match
|
|
||||||
# :type v: int
|
|
||||||
# :param pure: Match only pure states
|
|
||||||
# :type pure: bool
|
|
||||||
# :raises KeyError: Unknown state
|
|
||||||
# :rtype: tuple
|
|
||||||
# :return: 0: Alias that input resolves to, 1: list of atomic states that matches the state
|
|
||||||
def match(self, v, pure=False):
|
def match(self, v, pure=False):
|
||||||
|
"""Match against all stored states.
|
||||||
|
|
||||||
|
If pure is set, only match against the single atomic state will be returned.
|
||||||
|
|
||||||
|
:param v: Integer state to match
|
||||||
|
:type v: int
|
||||||
|
:param pure: Match only pure states
|
||||||
|
:type pure: bool
|
||||||
|
:raises KeyError: Unknown state
|
||||||
|
:rtype: tuple
|
||||||
|
:return: 0: Alias that input resolves to, 1: list of atomic states that matches the state
|
||||||
|
"""
|
||||||
alias = None
|
alias = None
|
||||||
if not pure:
|
if not pure:
|
||||||
alias = self.__reverse.get(v)
|
alias = self.__reverse.get(v)
|
||||||
@ -242,23 +249,24 @@ class State:
|
|||||||
return (alias, r,)
|
return (alias, r,)
|
||||||
|
|
||||||
|
|
||||||
# Add a key to an existing state.
|
|
||||||
#
|
|
||||||
# If no state it specified, the default state attribute "NEW" will be used.
|
|
||||||
#
|
|
||||||
# Contents may be supplied as value to pair with the given key. Contents may be changed later by calling the `replace` method.
|
|
||||||
#
|
|
||||||
# :param key: Content key to add
|
|
||||||
# :type key: str
|
|
||||||
# :param state: Initial state for the put. If not given, initial state will be NEW
|
|
||||||
# :type state: int
|
|
||||||
# :param contents: Contents to associate with key. A valie of None should be recognized as an undefined value as opposed to a zero-length value throughout any backend
|
|
||||||
# :type contents: str
|
|
||||||
# :raises StateItemExists: Content key has already been added
|
|
||||||
# :raises StateInvalid: Given state has not been registered
|
|
||||||
# :rtype: integer
|
|
||||||
# :return: Resulting state that key is put under (should match the input state)
|
|
||||||
def put(self, key, state=None, contents=None):
|
def put(self, key, state=None, contents=None):
|
||||||
|
"""Add a key to an existing state.
|
||||||
|
|
||||||
|
If no state it specified, the default state attribute "NEW" will be used.
|
||||||
|
|
||||||
|
Contents may be supplied as value to pair with the given key. Contents may be changed later by calling the `replace` method.
|
||||||
|
|
||||||
|
:param key: Content key to add
|
||||||
|
:type key: str
|
||||||
|
:param state: Initial state for the put. If not given, initial state will be NEW
|
||||||
|
:type state: int
|
||||||
|
:param contents: Contents to associate with key. A valie of None should be recognized as an undefined value as opposed to a zero-length value throughout any backend
|
||||||
|
:type contents: str
|
||||||
|
:raises StateItemExists: Content key has already been added
|
||||||
|
:raises StateInvalid: Given state has not been registered
|
||||||
|
:rtype: integer
|
||||||
|
:return: Resulting state that key is put under (should match the input state)
|
||||||
|
"""
|
||||||
if state == None:
|
if state == None:
|
||||||
state = self.NEW
|
state = self.NEW
|
||||||
elif self.__reverse.get(state) == None:
|
elif self.__reverse.get(state) == None:
|
||||||
@ -271,17 +279,18 @@ class State:
|
|||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
# Move a given content key from one state to another.
|
|
||||||
#
|
|
||||||
# :param key: Key to move
|
|
||||||
# :type key: str
|
|
||||||
# :param to_state: Numeric state to move to (may be atomic or alias)
|
|
||||||
# :type to_state: integer
|
|
||||||
# :raises StateItemNotFound: Given key has not been registered
|
|
||||||
# :raises StateInvalid: Given state has not been registered
|
|
||||||
# :rtype: integer
|
|
||||||
# :return: Resulting state from move (should match the state given as input)
|
|
||||||
def move(self, key, to_state):
|
def move(self, key, to_state):
|
||||||
|
"""Move a given content key from one state to another.
|
||||||
|
|
||||||
|
:param key: Key to move
|
||||||
|
:type key: str
|
||||||
|
:param to_state: Numeric state to move to (may be atomic or alias)
|
||||||
|
:type to_state: integer
|
||||||
|
:raises StateItemNotFound: Given key has not been registered
|
||||||
|
:raises StateInvalid: Given state has not been registered
|
||||||
|
:rtype: integer
|
||||||
|
:return: Resulting state from move (should match the state given as input)
|
||||||
|
"""
|
||||||
current_state = self.__keys_reverse.get(key)
|
current_state = self.__keys_reverse.get(key)
|
||||||
if current_state == None:
|
if current_state == None:
|
||||||
raise StateItemNotFound(key)
|
raise StateItemNotFound(key)
|
||||||
@ -311,18 +320,19 @@ class State:
|
|||||||
return to_state
|
return to_state
|
||||||
|
|
||||||
|
|
||||||
# Move to an alias state by setting a single bit.
|
|
||||||
#
|
|
||||||
# :param key: Content key to modify state for
|
|
||||||
# :type key: str
|
|
||||||
# :param or_state: Atomic stat to add
|
|
||||||
# :type or_state: int
|
|
||||||
# :raises ValueError: State is not a single bit state
|
|
||||||
# :raises StateItemNotFound: Content key is not registered
|
|
||||||
# :raises StateInvalid: Resulting state after addition of atomic state is unknown
|
|
||||||
# :rtype: int
|
|
||||||
# :returns: Resulting state
|
|
||||||
def set(self, key, or_state):
|
def set(self, key, or_state):
|
||||||
|
"""Move to an alias state by setting a single bit.
|
||||||
|
|
||||||
|
:param key: Content key to modify state for
|
||||||
|
:type key: str
|
||||||
|
:param or_state: Atomic stat to add
|
||||||
|
:type or_state: int
|
||||||
|
:raises ValueError: State is not a single bit state
|
||||||
|
:raises StateItemNotFound: Content key is not registered
|
||||||
|
:raises StateInvalid: Resulting state after addition of atomic state is unknown
|
||||||
|
:rtype: int
|
||||||
|
:returns: Resulting state
|
||||||
|
"""
|
||||||
if not self.__is_pure(or_state):
|
if not self.__is_pure(or_state):
|
||||||
raise ValueError('can only apply using single bit states')
|
raise ValueError('can only apply using single bit states')
|
||||||
|
|
||||||
@ -338,20 +348,21 @@ class State:
|
|||||||
return self.__move(key, current_state, to_state)
|
return self.__move(key, current_state, to_state)
|
||||||
|
|
||||||
|
|
||||||
# Unset a single bit, moving to a pure or alias state.
|
|
||||||
#
|
|
||||||
# The resulting state cannot be NEW (0).
|
|
||||||
#
|
|
||||||
# :param key: Content key to modify state for
|
|
||||||
# :type key: str
|
|
||||||
# :param or_state: Atomic stat to add
|
|
||||||
# :type or_state: int
|
|
||||||
# :raises ValueError: State is not a single bit state, or attempts to revert to NEW
|
|
||||||
# :raises StateItemNotFound: Content key is not registered
|
|
||||||
# :raises StateInvalid: Resulting state after addition of atomic state is unknown
|
|
||||||
# :rtype: int
|
|
||||||
# :returns: Resulting state
|
|
||||||
def unset(self, key, not_state):
|
def unset(self, key, not_state):
|
||||||
|
"""Unset a single bit, moving to a pure or alias state.
|
||||||
|
|
||||||
|
The resulting state cannot be NEW (0).
|
||||||
|
|
||||||
|
:param key: Content key to modify state for
|
||||||
|
:type key: str
|
||||||
|
:param or_state: Atomic stat to add
|
||||||
|
:type or_state: int
|
||||||
|
:raises ValueError: State is not a single bit state, or attempts to revert to NEW
|
||||||
|
:raises StateItemNotFound: Content key is not registered
|
||||||
|
:raises StateInvalid: Resulting state after addition of atomic state is unknown
|
||||||
|
:rtype: int
|
||||||
|
:returns: Resulting state
|
||||||
|
"""
|
||||||
if not self.__is_pure(not_state):
|
if not self.__is_pure(not_state):
|
||||||
raise ValueError('can only apply using single bit states')
|
raise ValueError('can only apply using single bit states')
|
||||||
|
|
||||||
@ -373,70 +384,76 @@ class State:
|
|||||||
return self.__move(key, current_state, to_state)
|
return self.__move(key, current_state, to_state)
|
||||||
|
|
||||||
|
|
||||||
# Return the current numeric state for the given content key.
|
|
||||||
#
|
|
||||||
# :param key: Key to return content for
|
|
||||||
# :type key: str
|
|
||||||
# :raises StateItemNotFound: Content key is unknown
|
|
||||||
# :rtype: int
|
|
||||||
# :returns: State
|
|
||||||
def state(self, key):
|
def state(self, key):
|
||||||
|
"""Return the current numeric state for the given content key.
|
||||||
|
|
||||||
|
:param key: Key to return content for
|
||||||
|
:type key: str
|
||||||
|
:raises StateItemNotFound: Content key is unknown
|
||||||
|
:rtype: int
|
||||||
|
:returns: State
|
||||||
|
"""
|
||||||
state = self.__keys_reverse.get(key)
|
state = self.__keys_reverse.get(key)
|
||||||
if state == None:
|
if state == None:
|
||||||
raise StateItemNotFound(key)
|
raise StateItemNotFound(key)
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
# Retrieve the content for a content key.
|
|
||||||
#
|
|
||||||
# :param key: Content key to retrieve content for
|
|
||||||
# :type key: str
|
|
||||||
# :rtype: any
|
|
||||||
# :returns: Content
|
|
||||||
def get(self, key):
|
def get(self, key):
|
||||||
|
"""Retrieve the content for a content key.
|
||||||
|
|
||||||
|
:param key: Content key to retrieve content for
|
||||||
|
:type key: str
|
||||||
|
:rtype: any
|
||||||
|
:returns: Content
|
||||||
|
"""
|
||||||
return self.__contents.get(key)
|
return self.__contents.get(key)
|
||||||
|
|
||||||
|
|
||||||
# List all content keys matching a state.
|
|
||||||
#
|
|
||||||
# :param state: State to match
|
|
||||||
# :type state: int
|
|
||||||
# :rtype: list of str
|
|
||||||
# :returns: Matching content keys
|
|
||||||
def list(self, state):
|
def list(self, state):
|
||||||
|
"""List all content keys matching a state.
|
||||||
|
|
||||||
|
:param state: State to match
|
||||||
|
:type state: int
|
||||||
|
:rtype: list of str
|
||||||
|
:returns: Matching content keys
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return self.__keys[state]
|
return self.__keys[state]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
# Noop method for interface implementation providing sync to backend.
|
|
||||||
#
|
|
||||||
# :param state: State to sync.
|
|
||||||
# :type state:
|
|
||||||
# :todo: (for higher level implementer) if sync state is none, sync all
|
|
||||||
def sync(self, state):
|
def sync(self, state):
|
||||||
|
"""Noop method for interface implementation providing sync to backend.
|
||||||
|
|
||||||
|
:param state: State to sync.
|
||||||
|
:type state:
|
||||||
|
:todo: (for higher level implementer) if sync state is none, sync all
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# In the memory-only class no persisted state is used, and this will return None.
|
|
||||||
#
|
|
||||||
# See shep.persist.PersistedState.path for more information.
|
|
||||||
def path(self, state, key=None):
|
def path(self, state, key=None):
|
||||||
|
"""In the memory-only class no persisted state is used, and this will return None.
|
||||||
|
|
||||||
|
See shep.persist.PersistedState.path for more information.
|
||||||
|
"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Return the next pure state.
|
|
||||||
#
|
|
||||||
# Will return the same result as the method next, but without advancing to the new state.
|
|
||||||
#
|
|
||||||
# :param key: Content key to inspect state for
|
|
||||||
# :type key: str
|
|
||||||
# :raises StateItemNotFound: Unknown content key
|
|
||||||
# :raises StateInvalid: Attempt to advance from an alias state, OR beyond the last known pure state.
|
|
||||||
# :rtype: int
|
|
||||||
# :returns: Next state
|
|
||||||
def peek(self, key):
|
def peek(self, key):
|
||||||
|
"""Return the next pure state.
|
||||||
|
|
||||||
|
Will return the same result as the method next, but without advancing to the new state.
|
||||||
|
|
||||||
|
:param key: Content key to inspect state for
|
||||||
|
:type key: str
|
||||||
|
:raises StateItemNotFound: Unknown content key
|
||||||
|
:raises StateInvalid: Attempt to advance from an alias state, OR beyond the last known pure state.
|
||||||
|
:rtype: int
|
||||||
|
:returns: Next state
|
||||||
|
"""
|
||||||
state = self.__keys_reverse.get(key)
|
state = self.__keys_reverse.get(key)
|
||||||
if state == None:
|
if state == None:
|
||||||
raise StateItemNotFound(key)
|
raise StateItemNotFound(key)
|
||||||
@ -453,27 +470,29 @@ class State:
|
|||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
# Advance to the next pure state.
|
|
||||||
#
|
|
||||||
# :param key: Content key to inspect state for
|
|
||||||
# :type key: str
|
|
||||||
# :raises StateItemNotFound: Unknown content key
|
|
||||||
# :raises StateInvalid: Attempt to advance from an alias state, OR beyond the last known pure state.
|
|
||||||
# :rtype: int
|
|
||||||
# :returns: Next state
|
|
||||||
def next(self, key):
|
def next(self, key):
|
||||||
|
"""Advance to the next pure state.
|
||||||
|
|
||||||
|
:param key: Content key to inspect state for
|
||||||
|
:type key: str
|
||||||
|
:raises StateItemNotFound: Unknown content key
|
||||||
|
:raises StateInvalid: Attempt to advance from an alias state, OR beyond the last known pure state.
|
||||||
|
:rtype: int
|
||||||
|
:returns: Next state
|
||||||
|
"""
|
||||||
from_state = self.state(key)
|
from_state = self.state(key)
|
||||||
new_state = self.peek(key)
|
new_state = self.peek(key)
|
||||||
return self.__move(key, from_state, new_state)
|
return self.__move(key, from_state, new_state)
|
||||||
|
|
||||||
|
|
||||||
# Replace contents associated by content key.
|
|
||||||
#
|
|
||||||
# :param key: Content key to replace for
|
|
||||||
# :type key: str
|
|
||||||
# :param contents: New contents
|
|
||||||
# :type contents: any
|
|
||||||
# :raises KeyError: Unknown content key
|
|
||||||
def replace(self, key, contents):
|
def replace(self, key, contents):
|
||||||
|
"""Replace contents associated by content key.
|
||||||
|
|
||||||
|
:param key: Content key to replace for
|
||||||
|
:type key: str
|
||||||
|
:param contents: New contents
|
||||||
|
:type contents: any
|
||||||
|
:raises KeyError: Unknown content key
|
||||||
|
"""
|
||||||
self.state(key)
|
self.state(key)
|
||||||
self.__contents[key] = contents
|
self.__contents[key] = contents
|
||||||
|
Loading…
Reference in New Issue
Block a user