Refactored ExecutionContext serialization (added sheerkapickle) and added History management
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user