commit 72b2bd43c28c351ec678960c4f48646adaa2ac1f
parent 98387157f583e2160fe7272ea07913e9b13cc152
Author: lash <dev@holbrook.no>
Date: Wed, 19 Apr 2023 11:39:07 +0100
Add optional create pure elements in from_elements method
Diffstat:
5 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
@@ -1,3 +1,5 @@
+- 0.3.1
+ * Add option to create missing pure state from from_elements call.
- 0.3.0
* Clean up lingering keys in lists when moving from alias state
* Properly set default state when set through instantiation
diff --git a/setup.cfg b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = shep
-version = 0.3.0
+version = 0.3.1
description = Multi-state key stores using bit masks
author = Louis Holbrook
author_email = dev@holbrook.no
diff --git a/shep/persist.py b/shep/persist.py
@@ -4,10 +4,12 @@ import datetime
# local imports
from .state import (
State,
+ split_elements,
)
from .error import (
StateItemExists,
StateLockedKey,
+ StateExists,
)
@@ -130,6 +132,19 @@ class PersistedState(State):
return self.__movestore(key, from_state, to_state)
+ def __ensure_parts(self, state):
+ if self.is_pure(state):
+ return
+ state_name = self.name(state)
+ parts = split_elements(state_name)
+ for k in parts:
+ try:
+ self.add(k)
+ except StateExists:
+ pass
+ self.__ensure_store(k)
+
+
# common procedure for safely moving a persisted resource from one state to another.
def __movestore(self, key, from_state, to_state):
k_from = self.name(from_state)
@@ -141,6 +156,8 @@ class PersistedState(State):
self.__stores[k_to].put(key, contents)
self.__stores[k_from].remove(key)
+ self.__ensure_parts(to_state)
+
self.register_modify(key)
self.sync(to_state)
@@ -245,7 +262,7 @@ class PersistedState(State):
def add(self, key):
self.__ensure_store(key)
- super(PersistedState, self).add(key)
+ return super(PersistedState, self).add(key)
def alias(self, key, *args):
diff --git a/shep/state.py b/shep/state.py
@@ -205,6 +205,7 @@ class State:
k = self.__check_name(k)
v = self.__check_value(v)
self.__set(k, v)
+ return v
def to_name(self, k):
@@ -305,12 +306,25 @@ class State:
return join_elements(r) #'_' + '.'.join(r)
- def from_elements(self, k):
+ def from_elements(self, k, create_missing=False):
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)
+ state = None
+ print("state {} {}".format(v, k))
+ try:
+ state = self.from_name(v)
+ except AttributeError as e:
+ pass
+
+ if state == None:
+ if not create_missing:
+ raise StateInvalid(v)
+ state = self.add(v)
+ print("state {} {} {}".format(v, k, state))
+
+ r |= state
return r
diff --git a/tests/test_state.py b/tests/test_state.py
@@ -355,5 +355,14 @@ class TestState(unittest.TestCase):
self.assertEqual(len(r), 0)
+
+ def test_generate_missing(self):
+ states = State(3)
+ with self.assertRaises(StateInvalid):
+ states.from_elements("_FOO__BAR")
+ states.from_elements("_FOO__BAR", create_missing=True)
+
+
+
if __name__ == '__main__':
unittest.main()