commit 52dffb80419d0ff368032a4c5426f878b9abf0e2
parent d915f17e2b7ee6a27aef51ab766b234a1366d4a3
Author: lash <dev@holbrook.no>
Date: Sun, 6 Nov 2022 16:36:13 +0000
Remove sticky list alias, fix instance default state
Diffstat:
6 files changed, 79 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
@@ -1,3 +1,7 @@
+- 0.3.0
+ * Clean up lingering keys in lists when moving from alias state
+ * Properly set default state when set through instantiation
+ * pass key to verifier (breaking change)
- 0.2.10
* Add count active states method
* Enable complete replace of NEW state on state instantiation
diff --git a/setup.cfg b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = shep
-version = 0.2.10
+version = 0.3.0
description = Multi-state key stores using bit masks
author = Louis Holbrook
author_email = dev@holbrook.no
diff --git a/shep/state.py b/shep/state.py
@@ -36,16 +36,20 @@ class State:
self.__limit = (1 << bits) - 1
self.__c = 0
+ self.__keys_reverse = {}
+
if default_state == None:
default_state = self.base_state_name
+ else:
+ default_state = self.__check_name_valid(default_state)
+ self.base_state_name = default_state
+ self.__keys_reverse[default_state] = 0
setattr(self, default_state, 0)
- self.__reverse = {0: getattr(self, default_state)}
- self.__keys = {getattr(self, default_state): []}
- self.__keys_reverse = {}
- if default_state != self.base_state_name:
- self.__keys_reverse[default_state] = 0
+ self.__reverse = {0: default_state}
+ self.__keys = {0: []}
+
self.__contents = {}
self.modified_last = {}
self.verifier = verifier
@@ -309,6 +313,8 @@ class State:
:return: Numeric state value
"""
k = self.__check_name_valid(k)
+ if k == self.base_state_name:
+ return 0
return getattr(self, k)
@@ -416,16 +422,19 @@ class State:
raise StateCorruptionError(to_state)
if self.verifier != None:
- r = self.verifier(self, from_state, to_state)
+ r = self.verifier(self, key, from_state, to_state)
if r != None:
raise StateTransitionInvalid(r)
- current_state_list.pop(idx)
-
+ old_state = self.__keys_reverse.get(key)
if self.event_callback != None:
- old_state = self.__keys_reverse.get(key)
self.event_callback(key, self.name(old_state), self.name(to_state))
+ if old_state == 0:
+ current_state_list.pop(idx)
+ else:
+ for k in self.elements(from_state, numeric=True):
+ self.__keys[k].remove(key)
self.__add_state_list(to_state, key)
self.register_modify(key)
@@ -542,6 +551,7 @@ class State:
:rtype: any
:returns: Content
"""
+ print('contents {}'.format(self.__contents))
return self.__contents.get(key)
diff --git a/shep/store/file.py b/shep/store/file.py
@@ -1,6 +1,7 @@
# standard imports
import os
import re
+import stat
# local imports
from .base import (
@@ -204,9 +205,26 @@ class SimpleFileStoreFactory(StoreFactory):
r = []
for v in os.listdir(self.__path):
if re.match(re_processedname, v):
- r.append(v)
+ fp = os.path.join(self.__path, v)
+ st = os.stat(fp)
+ if stat.S_ISDIR(st.st_mode):
+ r.append(v)
return r
+ def have(self, k):
+ lock_path = None
+ if self.__use_lock:
+ lock_path = os.path.join(self.__path, '.lock')
+ for d in self.ls():
+ p = os.path.join(self.__path, d)
+ s = SimpleFileStore(p, binary=self.__binary, lock_path=lock_path)
+ try:
+ s.get(k)
+ except:
+ return False
+ return True
+
+
def close(self):
pass
diff --git a/tests/test_state.py b/tests/test_state.py
@@ -318,8 +318,42 @@ class TestState(unittest.TestCase):
states = State(2, default_state='FOO')
with self.assertRaises(StateItemNotFound):
states.state('NEW')
- getattr(states, 'FOO')
+ r = getattr(states, 'FOO')
+ self.assertEqual(r, 0)
states.state('FOO')
+ states.put('bar')
+ r = states.list(states.FOO)
+ print(r)
+ self.assertEqual(len(r), 1)
+
+
+ def test_unset(self):
+ states = State(2)
+ states.add('one')
+ states.add('two')
+ states.alias('three', states.ONE, states.TWO)
+ states.put('foo', state=states.ONE)
+ states.set('foo', states.TWO)
+ r = states.list(states.ONE)
+ self.assertEqual(len(r), 1)
+ r = states.list(states.TWO)
+ self.assertEqual(len(r), 1)
+ r = states.unset('foo', states.ONE)
+ r = states.list(states.ONE)
+ self.assertEqual(len(r), 0)
+ r = states.list(states.TWO)
+ self.assertEqual(len(r), 1)
+
+
+ def test_move(self):
+ states = State(1)
+ states.add('one')
+ states.put('foo')
+ r = states.list(states.NEW)
+ self.assertEqual(len(r), 1)
+ states.move('foo', states.ONE)
+ r = states.list(states.NEW)
+ self.assertEqual(len(r), 0)
if __name__ == '__main__':
diff --git a/tests/test_verify.py b/tests/test_verify.py
@@ -8,7 +8,7 @@ from shep.error import (
)
-def mock_verify(state, from_state, to_state):
+def mock_verify(state, key, from_state, to_state):
if from_state == state.FOO:
if to_state == state.BAR:
return 'bar cannot follow foo'