1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
from common import *
import json
DUMPABLE_CLASSES_BY_NAME = {}
DUMPABLE_CLASS_NAMES = {}
DUMPABLE_PROXIES = {}
LOADABLE_PROXIES = {}
def dumpClassAs(cls, name):
def __add_it(function):
DUMPABLE_PROXIES[cls] = (name, function)
return function
return __add_it
def loadClassFrom(name):
def __add_it(function):
LOADABLE_PROXIES[name] = function
return function
return __add_it
def dumpable(name):
def __add_it(cls):
DUMPABLE_CLASSES_BY_NAME[name] = cls
DUMPABLE_CLASS_NAMES[cls] = name
return cls
return __add_it
def dump(rootObj):
def _dumpPiece(piece):
try:
clsObj = type(piece)
clsName = DUMPABLE_CLASS_NAMES[clsObj]
except KeyError:
# let's give this one more shot with the dumpable proxies
try:
dumpName, dumpFunc = DUMPABLE_PROXIES[clsObj]
except KeyError:
return piece
dest = dumpFunc(piece)
dest['_t'] = dumpName
return dest
dest = {'_t': clsName}
for attrName in clsObj.__dump_attribs__:
dest[attrName] = getattr(piece, attrName)
if hasattr(piece, '_dump'):
piece._dump(rootObj, dest)
return dest
return json.dumps(rootObj, default=_dumpPiece)
def load(string):
needsSpecialCare = []
def _loadObject(source):
try:
clsName = source['_t']
clsObj = DUMPABLE_CLASSES_BY_NAME[clsName]
print "Loading %s" % clsName
except KeyError:
# let's give this one more shot with the loadable proxies
try:
loadFunc = LOADABLE_PROXIES[clsName]
except KeyError:
return source
return loadFunc(source)
obj = clsObj()
for attrName in clsObj.__dump_attribs__:
setattr(obj, attrName, source[attrName])
if hasattr(obj, '_preload'):
obj._preload(source)
if hasattr(obj, '_load'):
needsSpecialCare.append((obj, source))
return obj
root = json.loads(string, object_hook=_loadObject)
for obj, source in needsSpecialCare:
obj._load(root, source)
return root
|