Code docstrings

master
Tom Wilson 6 years ago
parent 3687a3686e
commit e5a9bfd7f3

@ -1,28 +1,62 @@
"""
Preserve, for when pickling is just a bit too intense
Preserve is a simple framework to painlessly convert your python objects and
data structures into a nested structure containing only primitive types.
While intended for use in serialisation, Preserve stops short of the actual
serialisation bit - you can then use whatever method you prefer to dump
the nested primitive structure to JSON, TOML, or some other message packing
or storage system - most of which handle all primitive types by default.
"""
from enum import Enum, auto
import inspect
class RestoreMethod(Enum):
DIRECT = auto()
INIT = auto()
CLASS_METHOD = auto()
#preserve, for when pickling is just a bit too intense
# The class key is a reserved dict key used to flag that the dict should be unpacked back out to a class instance
class_key = "<_jam>"
# The Preserve module stores some state from init to keep a list of valid packable classes
"""
Contains the reserved dict key used to indicate that the dict it is in
should be restored to a class instance, not just treated as a dict.
Set to ``<_jam>`` by default. If changed externally, must be set before
any ``@preservable`` decorators
"""
preservables = {}
"""
A dict of classes marked as ``@preservable``, used to restore them back
to class instances.
"""
# Decorator to mark class as packable and keep track of associated names and classes. When packed, the
# special key string "<packable>" indicates what class the current dict should be unpacked to
# name argument is the string that will identify this class in a packed dict
def preservable(cls, restore_method=RestoreMethod.DIRECT, name=None):
"""
Decorator to mark class as preservable and keep track of associated names
and classes.
Args:
restore_method: One of the available preserve.RestoreMethod values.
Sets the method used for restoring this class. Defaults to
``DIRECT``, skipping the ``__init__`` method and setting all
attributes as they were.
name: The string used to indentify this class in the preserved dict.
Must be unique among all ``@preservable`` classes. Defaults to the
class name if left as None.
"""
if name is None:
cls._preserve_name = cls.__name__
else:
if isinstance(name, str):
raise Exception("preservable name must be a string")
raise Exception("Preservable name must be a string")
cls._preserve_name = name
cls._restore_method = restore_method
@ -40,6 +74,18 @@ def preservable(cls, restore_method=RestoreMethod.DIRECT, name=None):
def preserve(target_obj):
"""
Preserve ``target_obj``, running through its contents recursively.
Args:
target_obj: The object to be preserved. This object and all its nested
contents must either be primitive types or objects of a
``@preservable`` class.
Returns:
The preserved data structure - a nested structure containing only primitive
types.
"""
# If it's a primitive, store it. If it's a dict or list, recursively preserve that.
# If it's an instance of another preservable class, call its .preserve() method.
if isinstance(target_obj, (str, int, float, bool, type(None))):
@ -56,6 +102,7 @@ def preserve(target_obj):
else:
raise Exception("Object "+str(target_obj)+" is not preservable")
def _preserve_dict(target_dict):
dict_jam = {}
for k, val in target_dict.items():
@ -66,7 +113,17 @@ def _preserve_dict(target_dict):
dict_jam[k] = preserve(val)
return dict_jam
def restore(obj_jam):
"""
Restore the result of ``preserve()`` back into its original form. Will
recursively scan the data structure and restore any
``@preservable`` classes according to their ``restore_method``.
Args:
obj_jam: The data structure to restore, usually the result of a
``preserve()`` call.
"""
if isinstance(obj_jam, (str, int, float, bool, type(None))):
return obj_jam
elif isinstance(obj_jam, dict):
@ -79,6 +136,7 @@ def restore(obj_jam):
else:
raise Exception("Object "+str(obj_jam)+" is not restorable")
def _restore_dict(dict_jam):
restored_dict = {}
for k, val in dict_jam.items():
@ -106,7 +164,8 @@ def _restore_dict(dict_jam):
else:
raise Exception("Class "+str(f_class)+" does not have classmethod 'restore()'")
else:
raise Exception("Class _restore_method "+str(f_class._restore_method)+" is not supported")
raise Exception("Class _restore_method " +
str(f_class._restore_method)+" is not supported")
return restored_instance
else:

Loading…
Cancel
Save