예제 #1
0
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
예제 #2
0
파일: jsonclass.py 프로젝트: CloudI/CloudI
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