Refactored ExecutionContext serialization (added sheerkapickle) and added History management

This commit is contained in:
2020-01-31 18:58:03 +01:00
parent fed0735eb9
commit b9afcba61f
31 changed files with 1546 additions and 518 deletions
+105
View File
@@ -0,0 +1,105 @@
import json
import core.utils
from sheerkapickle import tags, utils, handlers
def decode(sheerka, obj):
return SheerkaUnpickler(sheerka).restore(json.loads(obj))
class SheerkaUnpickler:
def __init__(self, sheerka):
self.sheerka = sheerka
self.objs = []
def restore(self, obj):
if has_tag(obj, tags.ID):
return self._restore_id(obj)
if has_tag(obj, tags.TUPLE):
return self._restore_tuple(obj)
if has_tag(obj, tags.SET):
return self._restore_set(obj)
if has_tag(obj, tags.ENUM):
return self._restore_enum(obj)
if has_tag(obj, tags.OBJECT):
return self._restore_obj(obj)
if utils.is_list(obj):
return self._restore_list(obj)
if utils.is_dictionary(obj):
return self._restore_dict(obj)
return obj
def _restore_list(self, obj):
return [self.restore(v) for v in obj]
def _restore_tuple(self, obj):
return tuple([self.restore(v) for v in obj[tags.TUPLE]])
def _restore_set(self, obj):
return set([self.restore(v) for v in obj[tags.SET]])
def _restore_enum(self, obj):
instance = core.utils.decode_enum(obj[tags.ENUM])
self.objs.append(instance)
return instance
def _restore_dict(self, obj):
data = {}
for k, v in obj.items():
resolved_key = self._resolve_key(k)
data[resolved_key] = self.restore(v)
return data
def _restore_id(self, obj):
try:
return self.objs[obj[tags.ID]]
except IndexError:
pass
def _restore_obj(self, obj):
handler = handlers.get(obj[tags.OBJECT])
if handler:
handler = handler(self.sheerka, self)
instance = handler.new(obj)
self.objs.append(instance)
instance = handler.restore(obj, instance)
else:
cls = core.utils.get_class(obj[tags.OBJECT])
instance = cls.__new__(cls)
self.objs.append(instance)
for k, v in obj.items():
if k == tags.OBJECT:
continue
value = self.restore(v)
setattr(instance, k, value)
return instance
def _resolve_key(self, key):
if key == "null":
return None
concept_key, concept_id = core.utils.decode_concept(key)
if concept_key is not None:
return self.sheerka.new((concept_key, concept_id)) if concept_id else self.sheerka.new(concept_key)
as_enum = core.utils.decode_enum(key)
if as_enum is not None:
return as_enum
return key
def has_tag(obj, tag):
return type(obj) is dict and tag in obj