Package: grave-settings
Grave SettingsA library for automatic serialization of python object hierarchies to storage. Most python objects are
compatible without any extra code, and there are several tools for fine-grain control.The framework uses either duck typing or strong typing to allow objects define custom behaviors and defines a Formatter
class to allow for user defined input/output formatsPre-defined formats:json (via built in json module)toml (read via tomlib, write enabled when tomli-w module is installed)bson (only tested experimentally)Red thedocumenationfor examples and important considerations.Installpip install grave-settingsFeaturesSave / Import types to reconstruct object hierarchiesPreserve "is" relationships automatically by scanning object idsAbstractions for object version management for easing continuous deploymentOrderedHandler objects allow for custom serialization / deserialization logic for types without using inheritance or duck typingDetect circular referencesEvent handlers for finalizing serialization / deserialization (intended to fix circular references)Semantic objects for communicating options to the formatter (ex. security options for loading of arbitrary types)Default standard handlersDefining new handlers or adding functionality to the default handlers is easy, but some types have already been done:NameDescriptionTypebuilt-in python type objectNoneTypeNoneIterableGeneral catch all for Iterable defined in collections moduleMappingGeneral catch all for Mapping defined in collections moduleFunctionTypePython user-defined functiondatefrom datetime moduledatetimefrom datetime module  (experimental timezone support)timedeltafrom datetime moduleEnumfrom enum modulepartialbuiltin partial classbytesbuiltin bytes dataComplex / Rationalbuiltin numerical classesPathfrom pathlibThere is still a ways to go before most of the built in types have handlers. To see how the handlers work read:default_handlers.pyIn progressValidation supportAutomated Qt GUI interface for editing settings objectsCode ExampleHere is a quick example that serializes and then deserializes a custom object hierarchy with the default built in classesfromdatetimeimportdatefromgrave_settings.formatters.tomlimportTomlFormatterclassColor:def__init__(self,r,g,b):self.r=rself.g=gself.b=bdef__str__(self):returnf'Color(r={self.r}, g={self.g}, b={self.b})'classMyObject:def__init__(self):self.integer=1self.string='b'self.function=print# demonstrates handling a functionself.type_object=int# demonstrates handling a type# demonstrates handling a list of date objectsself.dates=[date(year=2022,month=1,day=1),date(year=2023,month=2,day=2)]# demonstrates handling a nested objectself.color=Color(255,255,255)formatter=TomlFormatter()obj_str=formatter.dumps(MyObject())print(obj_str)This will output:__class__="__main__.MyObject"integer=1string="b"[function]__class__="types.FunctionType"state="builtins.print"[type_object]__class__="builtins.type"state="builtins.int"[[dates]]__class__="datetime.date"state=[2022,1,1,][[dates]]__class__="datetime.date"state=[2023,2,2,][color]__class__="__main__.Color"r=255g=255b=255Now if we take this string and deserialize it with the same (or equivalent) formatter:fromgrave_settings.formatters.tomlimportTomlFormatterformatter=TomlFormatter()remade_obj=formatter.loads(obj_str)print(f'''integer ={remade_obj.integer}string ={remade_obj.string}function ={remade_obj.function}type_object ={remade_obj.type_object}dates ={remade_obj.dates}color ={remade_obj.color}''')We get:integer = 1
string = b
function = <built-in function print>
type_object = <class 'int'>
dates = [datetime.date(2022, 1, 1), datetime.date(2023, 2, 2)]
color = Color(r=255, g=255, b=255)It is recommended to use the Serializable type (in this module) or handlers instead of using the naked objects like above.
Read the documentation for more on this.