shep

Multi-state key stores using bit masks for python3
git clone git://git.defalsify.org/shep.git
Log | Files | Refs | LICENSE

commit 0c76507f5fb18c1dcaee880cbcb63b1b66916055
parent 2beeb4c725d2d6eedd93c09502c52f475f21a166
Author: lash <dev@holbrook.no>
Date:   Wed, 23 Mar 2022 23:34:13 +0000

Sync unknown states in persistent store

Diffstat:
Mshep/persist.py | 4++++
Mshep/state.py | 32++++++++++++++++++++++++--------
Mshep/store/file.py | 2+-
Mtests/test_state.py | 10++++++++++
4 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/shep/persist.py b/shep/persist.py @@ -58,6 +58,8 @@ class PersistedState(State): self.__stores[k_to].add(key, contents) self.__stores[k_from].remove(key) + self.sync(to_state) + return to_state @@ -126,6 +128,8 @@ class PersistedState(State): self.register_modify(key) + self.sync(to_state) + return to_state diff --git a/shep/state.py b/shep/state.py @@ -150,6 +150,9 @@ class State: self.__keys[part].append(item) c <<= 1 self.__keys_reverse[item] = state + if self.__reverse.get(state) == None: + s = self.elements(state) + self.alias(s, state) def __state_list_index(self, item, state_list): @@ -234,7 +237,16 @@ class State: if v & c > 0: r.append(self.name(c)) c <<= 1 - return '*' + ','.join(r) + return '_' + '_'.join(r) + + + def from_elements(self, k): + r = 0 + if k[0] != '_': + raise ValueError('elements string must start with underscore (_), got {}'.format(k)) + for v in k[1:].split('_'): + r |= self.from_name(v) + return r def name(self, v): @@ -325,14 +337,16 @@ class State: elif self.__reverse.get(state) == None and self.check_alias: raise StateInvalid(state) self.__check_key(key) + + if self.event_callback != None: + old_state = self.__keys_reverse.get(key) + self.event_callback(key, 'nonexistent', self.name(state)) + self.__add_state_list(state, key) if contents != None: self.__contents[key] = contents self.register_modify(key) - - if self.event_callback != None: - self.event_callback(key, state) return state @@ -378,13 +392,15 @@ class State: raise StateTransitionInvalid(r) current_state_list.pop(idx) + + if self.event_callback != None: + old_state = self.__keys_reverse.get(key) + self.event_callback(key, self.name(old_state), self.name(to_state)) + self.__add_state_list(to_state, key) self.register_modify(key) - if self.event_callback != None: - self.event_callback(key, to_state) - return to_state @@ -596,7 +612,7 @@ class State: self.modified_last[key] = datetime.datetime.now().timestamp() - def mask(self, key, states): + def mask(self, key, states=0): statemask = self.__limit + 1 statemask |= states statemask = ~statemask diff --git a/shep/store/file.py b/shep/store/file.py @@ -15,7 +15,7 @@ class SimpleFileStore: self.__m = ['rb', 'wb'] else: self.__m = ['r', 'w'] - + def add(self, k, contents=None): """Add a new key and optional contents diff --git a/tests/test_state.py b/tests/test_state.py @@ -237,5 +237,15 @@ class TestState(unittest.TestCase): self.assertEqual(mask, states.BAR) + def test_mask_zero(self): + states = State(0) + states.add('foo') + states.add('bar') + states.add('baz') + states.alias('all', states.FOO | states.BAR | states.BAZ) + mask = states.mask('xyzzy') + self.assertEqual(mask, states.ALL) + + if __name__ == '__main__': unittest.main()