From c68880656aee85f8879fd969db13dc3ce6c4ee72 Mon Sep 17 00:00:00 2001 From: "Loibl Johannes (IFAG DES SDF SCS SEM)" Date: Wed, 29 Jun 2022 09:21:59 +0200 Subject: [PATCH 1/3] Fix for #302 --- apptools/persistence/state_pickler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apptools/persistence/state_pickler.py b/apptools/persistence/state_pickler.py index 019dcf9d..af7c4662 100644 --- a/apptools/persistence/state_pickler.py +++ b/apptools/persistence/state_pickler.py @@ -775,7 +775,7 @@ def set(self, obj, state, ignore=None, first=None, last=None): for name in ignore: try: state_keys.remove(name) - except KeyError: + except ValueError: pass # Do the `first` attributes. From c752239d768c23ebc77907c2580b2ef1dfa68f1d Mon Sep 17 00:00:00 2001 From: "Loibl Johannes (IFAG DES SDF SCS SEM)" Date: Wed, 29 Jun 2022 09:35:25 +0200 Subject: [PATCH 2/3] Fix for #302 part 2 Make sure ignore, first, last are propagated to nested set() calls --- apptools/persistence/state_pickler.py | 41 ++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/apptools/persistence/state_pickler.py b/apptools/persistence/state_pickler.py index af7c4662..85003faa 100644 --- a/apptools/persistence/state_pickler.py +++ b/apptools/persistence/state_pickler.py @@ -694,7 +694,31 @@ class StateSetter: that when it sets the state. """ - def __init__(self): + def __init__(self, ignore=None, first=None, last=None): + """Sets the state of the object. + + Parameters + ---------- + + - ignore : `list(str)` + + The list of attributes specified in this list are ignored + and the state of these attributes are not set (this excludes + the ones specified in `first` and `last`). If one specifies + a '*' then all attributes are ignored except the ones + specified in `first` and `last`. + + - first : `list(str)` + + The list of attributes specified in this list are set first (in + order), before any other attributes are set. + + - last : `list(str)` + + The list of attributes specified in this list are set last (in + order), after all other attributes are set. + + """ # Stores the ids of instances already done. self._instance_ids = [] self.type_map = { @@ -703,6 +727,9 @@ def __init__(self): StateList: self._do_list, StateDict: self._do_dict, } + self.ignore = ignore + self.first = first + self.last = last def set(self, obj, state, ignore=None, first=None, last=None): """Sets the state of the object. @@ -757,15 +784,15 @@ def set(self, obj, state, ignore=None, first=None, last=None): self._register(obj) - # This wierdness is needed since the state's own `keys` might + # This weirdness is needed since the state's own `keys` might # be set to something else. state_keys = list(dict.keys(state)) state_keys.remove("__metadata__") - if first is None: - first = [] - if last is None: - last = [] + # fallback to instance default + first = first or self.first or [] + last = last or self.last or [] + ignore = ignore or self.ignore or [] # Remove all the ignored keys. if ignore: @@ -998,7 +1025,7 @@ def get_state(obj): def set_state(obj, state, ignore=None, first=None, last=None): - StateSetter().set(obj, state, ignore, first, last) + StateSetter(ignore, first, last).set(obj, state, ignore, first, last) set_state.__doc__ = StateSetter.set.__doc__ From f2bc2b20c70f6dc264c609db4a14415a4090133f Mon Sep 17 00:00:00 2001 From: "Loibl Johannes (IFAG DES SDF SCS SEM)" Date: Wed, 29 Jun 2022 10:07:18 +0200 Subject: [PATCH 3/3] Fix for #310 --- apptools/persistence/state_pickler.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/apptools/persistence/state_pickler.py b/apptools/persistence/state_pickler.py index 85003faa..56bbd107 100644 --- a/apptools/persistence/state_pickler.py +++ b/apptools/persistence/state_pickler.py @@ -939,20 +939,29 @@ def _do_list(self, obj, state): if not self._has_instance(state[i]): obj[i] = self._get_pure(state[i]) elif isinstance(state[i], tuple): - obj[i] = self._do_tuple(state[i]) + obj[i] = self._do_tuple(obj[i], state[i]) else: self._do_object(obj[i], state[i]) else: - raise StateSetterError( - "Cannot set state of list of incorrect size." - ) + # dynamically increase list so restoring works + obj.clear() + for i in range(len(state)): + if not self._has_instance(state[i]): + new_item = self._get_pure(state[i]) + elif isinstance(state[i], tuple): + new_item = self._do_tuple(obj, state[i]) + else: + new_item = create_instance(state[i]) + self._do_object(new_item, state[i]) + obj.append(new_item) def _do_dict(self, obj, state): + obj.clear() for key, value in state.items(): if not self._has_instance(value): obj[key] = self._get_pure(value) elif isinstance(value, tuple): - obj[key] = self._do_tuple(value) + obj[key] = self._do_tuple(obj, value) else: self._do_object(obj[key], value)