6 from jsonrpclib import config
30 supported_types = iter_types+string_types+numeric_types+value_types
31 invalid_module_chars = r'[^a-zA-Z0-9\_\.]'
33 class TranslationError(Exception):
36 def dump(obj, serialize_method=None, ignore_attribute=None, ignore=[]):
37 if not serialize_method:
38 serialize_method = config.serialize_method
39 if not ignore_attribute:
40 ignore_attribute = config.ignore_attribute
42 # Parse / return default "types"...
43 if obj_type in numeric_types+string_types+value_types:
45 if obj_type in iter_types:
46 if obj_type in (types.ListType, types.TupleType):
49 new_obj.append(dump(item, serialize_method,
50 ignore_attribute, ignore))
51 if obj_type is types.TupleType:
52 new_obj = tuple(new_obj)
57 for key, value in obj.iteritems():
58 new_obj[key] = dump(value, serialize_method,
59 ignore_attribute, ignore)
61 # It's not a standard type, so it needs __jsonclass__
62 module_name = inspect.getmodule(obj).__name__
63 class_name = obj.__class__.__name__
64 json_class = class_name
65 if module_name not in ['', '__main__']:
66 json_class = '%s.%s' % (module_name, json_class)
67 return_obj = {"__jsonclass__":[json_class,]}
68 # If a serialization method is defined..
69 if serialize_method in dir(obj):
70 # Params can be a dict (keyword) or list (positional)
71 # Attrs MUST be a dict.
72 serialize = getattr(obj, serialize_method)
73 params, attrs = serialize()
74 return_obj['__jsonclass__'].append(params)
75 return_obj.update(attrs)
77 # Otherwise, try to figure it out
78 # Obviously, we can't assume to know anything about the
79 # parameters passed to __init__
80 return_obj['__jsonclass__'].append([])
82 ignore_list = getattr(obj, ignore_attribute, [])+ignore
83 for attr_name, attr_value in obj.__dict__.iteritems():
84 if type(attr_value) in supported_types and \
85 attr_name not in ignore_list and \
86 attr_value not in ignore_list:
87 attrs[attr_name] = dump(attr_value, serialize_method,
88 ignore_attribute, ignore)
89 return_obj.update(attrs)
93 if type(obj) in string_types+numeric_types+value_types:
95 if type(obj) is types.ListType:
98 return_list.append(load(entry))
100 # Othewise, it's a dict type
101 if '__jsonclass__' not in obj.keys():
103 for key, value in obj.iteritems():
104 new_value = load(value)
105 return_dict[key] = new_value
107 # It's a dict, and it's a __jsonclass__
108 orig_module_name = obj['__jsonclass__'][0]
109 params = obj['__jsonclass__'][1]
110 if orig_module_name == '':
111 raise TranslationError('Module name empty.')
112 json_module_clean = re.sub(invalid_module_chars, '', orig_module_name)
113 if json_module_clean != orig_module_name:
114 raise TranslationError('Module name %s has invalid characters.' %
116 json_module_parts = json_module_clean.split('.')
118 if len(json_module_parts) == 1:
119 # Local class name -- probably means it won't work
120 if json_module_parts[0] not in config.classes.keys():
121 raise TranslationError('Unknown class or module %s.' %
122 json_module_parts[0])
123 json_class = config.classes[json_module_parts[0]]
125 json_class_name = json_module_parts.pop()
126 json_module_tree = '.'.join(json_module_parts)
128 temp_module = __import__(json_module_tree)
130 raise TranslationError('Could not import %s from module %s.' %
131 (json_class_name, json_module_tree))
132 json_class = getattr(temp_module, json_class_name)
133 # Creating the object...
135 if type(params) is types.ListType:
136 new_obj = json_class(*params)
137 elif type(params) is types.DictType:
138 new_obj = json_class(**params)
140 raise TranslationError('Constructor args must be a dict or list.')
141 for key, value in obj.iteritems():
142 if key == '__jsonclass__':
144 setattr(new_obj, key, value)