def dump(obj, serialize_method=None, ignore_attribute=None, ignore=None, config=jsonrpclib.config.DEFAULT): """ Transforms the given object into a JSON-RPC compliant form. Converts beans into dictionaries with a __jsonclass__ entry. Doesn't change primitive types. :param obj: An object to convert :param serialize_method: Custom serialization method :param ignore_attribute: Name of the object attribute containing the names of members to ignore :param ignore: A list of members to ignore :param config: A JSONRPClib Config instance :return: A JSON-RPC compliant object """ # Normalize arguments serialize_method = serialize_method or config.serialize_method ignore_attribute = ignore_attribute or config.ignore_attribute ignore = ignore or [] # Parse / return default "types"... # Apply additional types, override built-in types # (reminder: config.serialize_handlers is a dict) try: serializer = config.serialize_handlers[type(obj)] except KeyError: # Not a serializer pass else: if serializer is not None: return serializer(obj, serialize_method, ignore_attribute, ignore, config) # Primitive if isinstance(obj, utils.PRIMITIVE_TYPES): return obj # Iterative elif isinstance(obj, utils.ITERABLE_TYPES): # List, set or tuple return [ dump(item, serialize_method, ignore_attribute, ignore, config) for item in obj ] elif isinstance(obj, utils.DictType): # Dictionary return { key: dump(value, serialize_method, ignore_attribute, ignore, config) for key, value in obj.items() } # It's not a standard type, so it needs __jsonclass__ module_name = inspect.getmodule(type(obj)).__name__ json_class = obj.__class__.__name__ if module_name not in ('', '__main__'): json_class = '{0}.{1}'.format(module_name, json_class) # Keep the class name in the returned object return_obj = {"__jsonclass__": [json_class]} # If a serialization method is defined.. if hasattr(obj, serialize_method): # Params can be a dict (keyword) or list (positional) # Attrs MUST be a dict. serialize = getattr(obj, serialize_method) params, attrs = serialize() return_obj['__jsonclass__'].append(params) return_obj.update(attrs) elif utils.is_enum(obj): # Add parameters for enumerations return_obj['__jsonclass__'].append([obj.value]) else: # Otherwise, try to figure it out # Obviously, we can't assume to know anything about the # parameters passed to __init__ return_obj['__jsonclass__'].append([]) # Prepare filtering lists known_types = SUPPORTED_TYPES + tuple(config.serialize_handlers) ignore_list = getattr(obj, ignore_attribute, []) + ignore # Find fields and filter them by name fields = _find_fields(obj) fields.difference_update(ignore_list) # Dump field values attrs = {} for attr_name in fields: attr_value = getattr(obj, attr_name) if isinstance(attr_value, known_types) and \ attr_value not in ignore_list: attrs[attr_name] = dump(attr_value, serialize_method, ignore_attribute, ignore, config) return_obj.update(attrs) return return_obj
def dump(obj, serialize_method=None, ignore_attribute=None, ignore=None, config=jsonrpclib.config.DEFAULT): """ Transforms the given object into a JSON-RPC compliant form. Converts beans into dictionaries with a __jsonclass__ entry. Doesn't change primitive types. :param obj: An object to convert :param serialize_method: Custom serialization method :param ignore_attribute: Name of the object attribute containing the names of members to ignore :param ignore: A list of members to ignore :param config: A JSONRPClib Config instance :return: A JSON-RPC compliant object """ # Normalize arguments serialize_method = serialize_method or config.serialize_method ignore_attribute = ignore_attribute or config.ignore_attribute ignore = ignore or [] # Parse / return default "types"... # Apply additional types, override built-in types # (reminder: config.serialize_handlers is a dict) try: serializer = config.serialize_handlers[type(obj)] except KeyError: # Not a serializer pass else: if serializer is not None: return serializer(obj, serialize_method, ignore_attribute, ignore, config) # Primitive if isinstance(obj, utils.PRIMITIVE_TYPES): return obj # Iterative elif isinstance(obj, utils.ITERABLE_TYPES): # List, set or tuple return [dump(item, serialize_method, ignore_attribute, ignore, config) for item in obj] elif isinstance(obj, utils.DictType): # Dictionary return {key: dump(value, serialize_method, ignore_attribute, ignore, config) for key, value in obj.items()} # It's not a standard type, so it needs __jsonclass__ module_name = inspect.getmodule(type(obj)).__name__ json_class = obj.__class__.__name__ if module_name not in ('', '__main__'): json_class = '{0}.{1}'.format(module_name, json_class) # Keep the class name in the returned object return_obj = {"__jsonclass__": [json_class]} # If a serialization method is defined.. if hasattr(obj, serialize_method): # Params can be a dict (keyword) or list (positional) # Attrs MUST be a dict. serialize = getattr(obj, serialize_method) params, attrs = serialize() return_obj['__jsonclass__'].append(params) return_obj.update(attrs) elif utils.is_enum(obj): # Add parameters for enumerations return_obj['__jsonclass__'].append([obj.value]) else: # Otherwise, try to figure it out # Obviously, we can't assume to know anything about the # parameters passed to __init__ return_obj['__jsonclass__'].append([]) # Prepare filtering lists known_types = SUPPORTED_TYPES + tuple(config.serialize_handlers) ignore_list = getattr(obj, ignore_attribute, []) + ignore # Find fields and filter them by name fields = _find_fields(obj) fields.difference_update(ignore_list) # Dump field values attrs = {} for attr_name in fields: attr_value = getattr(obj, attr_name) if isinstance(attr_value, known_types) and \ attr_value not in ignore_list: attrs[attr_name] = dump(attr_value, serialize_method, ignore_attribute, ignore, config) return_obj.update(attrs) return return_obj