def test_config_custom(self):
        """
        Tests configured custom serializer
        """
        # Get the current time object
        now = datetime.datetime.now()

        # Check if it is correctly serialized
        std_serialized = dump(now)
        self.assertEqual(std_serialized['__jsonclass__'][0],
                         'datetime.datetime')

        # Configure a custom serializer
        def datetime_serializer(obj, serialize_method, ignore_attribute,
                                ignore, config):
            """
            Custom datetime serializer (returns an ISO date string)
            """
            self.assertIs(type(obj), datetime.datetime)
            return obj.isoformat()

        handlers = {datetime.datetime: datetime_serializer}
        config = jsonrpclib.config.Config(serialize_handlers=handlers)

        # Dump with out configuration
        custom_serialized = dump(now, config=config)

        # This should be a raw string
        self.assertEqual(custom_serialized, now.isoformat())
    def test_config_custom(self):
        """
        Tests configured custom serializer
        """
        # Get the current time object
        now = datetime.datetime.now()

        # Check if it is correctly serialized
        std_serialized = dump(now)
        self.assertEqual(
            std_serialized["__jsonclass__"][0], "datetime.datetime"
        )

        # Configure a custom serializer
        def datetime_serializer(
            obj, serialize_method, ignore_attribute, ignore, config
        ):
            """
            Custom datetime serializer (returns an ISO date string)
            """
            self.assertIs(type(obj), datetime.datetime)
            return obj.isoformat()

        handlers = {datetime.datetime: datetime_serializer}
        config = jsonrpclib.config.Config(serialize_handlers=handlers)

        # Dump with out configuration
        custom_serialized = dump(now, config=config)

        # This should be a raw string
        self.assertEqual(custom_serialized, now.isoformat())
    def test_iterable(self):
        """
        Tests dump & load of iterable types
        """
        tuple_values = (42, 42.12, "string", True, False, None)
        list_values = list(tuple_values)
        set_values = set(tuple_values)
        frozen_values = frozenset(tuple_values)

        for iterable in (tuple_values, list_values, set_values, frozen_values):
            # Dump...
            serialized = dump(iterable)
            # Reload...
            deserialized = load(serialized)

            self.assertIs(
                type(serialized), list, "Dumped iterable should be a list"
            )
            self.assertIs(
                type(deserialized), list, "Loaded iterable should be a list"
            )

            # Check content
            self.assertCountEqual(
                deserialized, tuple_values, "Values order changed"
            )
    def test_primitive(self):
        """
        Tests dump & load of primitive types
        """
        for value in (42, 42.12, "string", True, False, None):
            # Dump..
            serialized = dump(value)
            # Reload...
            deserialized = load(serialized)

            self.assertIs(
                type(serialized),
                type(value),
                "Type changed during serialization",
            )
            self.assertIs(
                type(deserialized),
                type(value),
                "Type changed during deserialization",
            )

            self.assertEqual(
                serialized, value, "Value changed during serialization"
            )
            self.assertEqual(
                deserialized, value, "Value changed during deserialization"
            )
Exemple #5
0
def dump(params=[], methodname=None, rpcid=None, version=None,
         is_response=None, is_notify=None, config=jsonrpclib.config.DEFAULT):
    """
    Prepares a JSON-RPC dictionary (request, notification, response or error)

    :param params: Method parameters (if a method name is given) or a Fault
    :param methodname: Method name
    :param rpcid: Request ID
    :param version: JSON-RPC version
    :param is_response: If True, this is a response dictionary
    :param is_notify: If True, this is a notification request
    :param config: A JSONRPClib Config instance
    :return: A JSON-RPC dictionary
    """
    # Default version
    if not version:
        version = config.version

    # Validate method name and parameters
    valid_params = (utils.TupleType, utils.ListType, utils.DictType, Fault)
    if methodname in utils.StringTypes and \
    not isinstance(params, valid_params):
        """
        If a method, and params are not in a listish or a Fault,
        error out.
        """
        raise TypeError('Params must be a dict, list, tuple or Fault instance.')

    # Prepares the JSON-RPC content
    payload = Payload(rpcid=rpcid, version=version)

    if type(params) is Fault:
        # Prepare an error dictionary
        return payload.error(params.faultCode, params.faultString)

    if type(methodname) not in utils.StringTypes and not is_response:
        # Neither a request nor a response
        raise ValueError('Method name must be a string, or is_response ' \
                         'must be set to True.')

    if config.use_jsonclass:
        # Use jsonclass to convert the parameters
        params = jsonclass.dump(params)

    if is_response:
        # Prepare a response dictionary
        if rpcid is None:
            # A response must have a request ID
            raise ValueError('A method response must have an rpcid.')
        return payload.response(params)

    if is_notify:
        # Prepare a notification dictionary
        return payload.notify(methodname, params)

    else:
        # Prepare a method call dictionary
        return payload.request(methodname, params)
    def test_object(self):
        """
        Tests dump & load of a custom type
        """
        types = {
            Bean: ("public", "_protected", "_Bean__private"),
            InheritanceBean: ("public", "_protected", "first", "_second"),
            SlotBean: ("public", "_protected"),
            InheritanceSlotBean: ("public", "_protected", "first", "_second"),
            SecondInheritanceSlotBean: (
                "public",
                "_protected",
                "first",
                "_second",
                "third",
                "_fourth",
            ),
        }

        for clazz, fields in types.items():
            # Prepare the bean
            data = clazz()

            # Dump it...
            serialized = dump(data)

            # Check serialized content
            self.assertIn("__jsonclass__", serialized)
            for field in fields:
                self.assertIn(field, serialized)

            # Check class name
            self.assertEqual(
                serialized["__jsonclass__"][0],
                "{0}.{1}".format(clazz.__module__, clazz.__name__),
            )

            # Reload it
            deserialized = load(serialized)

            # Dictionary is left as-is
            self.assertIn(
                "__jsonclass__",
                serialized,
                "Serialized dictionary has been modified",
            )
            self.assertFalse(
                hasattr(deserialized, "__jsonclass__"),
                "The deserialized bean shouldn't have a "
                "__jsonclass__ attribute",
            )

            # Check deserialized value
            self.assertIs(type(deserialized), type(data))
            self.assertEqual(
                deserialized, data, "Source and deserialized bean are not equal"
            )
    def test_enum(self):
        """
        Tests the serialization of enumerations
        """
        if enum is None:
            self.skipTest("enum package not available.")

        for data in (Color.BLUE, Color.RED):
            # Serialization
            enum_serialized = dump(data)
            self.assertIn(Color.__name__, enum_serialized["__jsonclass__"][0])
            self.assertEqual(data.value, enum_serialized["__jsonclass__"][1][0])

            # Loading
            result = load(enum_serialized)
            self.assertEqual(data, result)

        # Embedded
        data = [Color.BLUE, Color.RED]
        serialized = dump(data)
        result = load(serialized)
        self.assertListEqual(data, result)
Exemple #8
0
def dumps(params=[],
          methodname=None,
          methodresponse=None,
          encoding=None,
          rpcid=None,
          version=None,
          notify=None):
    """
    This differs from the Python implementation in that it implements
    the rpcid argument since the 2.0 spec requires it for responses.
    """
    if not version:
        version = config.version
    valid_params = (types.TupleType, types.ListType, types.DictType)
    if methodname in types.StringTypes and \
            type(params) not in valid_params and \
            not isinstance(params, Fault):
        """
        If a method, and params are not in a listish or a Fault,
        error out.
        """
        raise TypeError('Params must be a dict, list, tuple or Fault ' +
                        'instance.')
    # Begin parsing object
    payload = Payload(rpcid=rpcid, version=version)
    if not encoding:
        encoding = 'utf-8'
    if type(params) is Fault:
        response = payload.error(params.faultCode, params.faultString)
        return jdumps(response, encoding=encoding)

    if type(methodname) not in types.StringTypes and \
            methodresponse is not True:
        raise ValueError(
            'Method name must be a string, or methodresponse must '
            'be set to True.')

    if config.use_jsonclass is True:
        from jsonrpclib import jsonclass
        params = jsonclass.dump(params)
    if methodresponse is True:
        if rpcid is None:
            raise ValueError('A method response must have an rpcid.')
        response = payload.response(params)
        return jdumps(response, encoding=encoding)
    request = None
    if notify is True:
        request = payload.notify(methodname, params)
    else:
        request = payload.request(methodname, params)
    return jdumps(request, encoding=encoding)
Exemple #9
0
    def test_enum(self):
        """
        Tests the serialization of enumerations
        """
        if enum is None:
            self.skipTest("enum package not available.")

        for data in (Color.BLUE, Color.RED):
            # Serialization
            enum_serialized = dump(data)
            self.assertIn(
                Color.__name__, enum_serialized['__jsonclass__'][0])
            self.assertEqual(
                data.value, enum_serialized['__jsonclass__'][1][0])

            # Loading
            result = load(enum_serialized)
            self.assertEqual(data, result)

        # Embedded
        data = [Color.BLUE, Color.RED]
        serialized = dump(data)
        result = load(serialized)
        self.assertListEqual(data, result)
Exemple #10
0
def dumps(
        params=[], methodname=None, methodresponse=None,
        encoding=None, rpcid=None, version=None, notify=None):
    """
    This differs from the Python implementation in that it implements
    the rpcid argument since the 2.0 spec requires it for responses.
    """
    if not version:
        version = config.version
    valid_params = (tuple, list, dict)
    if methodname in types.StringTypes and \
            type(params) not in valid_params and \
            not isinstance(params, Fault):
        """
        If a method, and params are not in a listish or a Fault,
        error out.
        """
        raise TypeError('Params must be a dict, list, tuple or Fault ' +
                        'instance.')
    # Begin parsing object
    payload = Payload(rpcid=rpcid, version=version)
    if not encoding:
        encoding = 'utf-8'
    if type(params) is Fault:
        response = payload.error(params.faultCode, params.faultString)
        return jdumps(response, encoding=encoding)

    if type(methodname) not in types.StringTypes and \
            methodresponse is not True:
        raise ValueError(
            'Method name must be a string, or methodresponse must '
            'be set to True.')

    if config.use_jsonclass is True:
        from jsonrpclib import jsonclass
        params = jsonclass.dump(params)
    if methodresponse is True:
        if rpcid is None:
            raise ValueError('A method response must have an rpcid.')
        response = payload.response(params)
        return jdumps(response, encoding=encoding)
    request = None
    if notify:
        request = payload.notify(methodname, params)
    else:
        request = payload.request(methodname, params)
    return jdumps(request, encoding=encoding)
    def test_dictionary(self):
        """
        Tests dump & load of dictionaries
        """
        dictionary = {'int': 42,
                      'float': 42.2,
                      None: "string",
                      True: False,
                      42.1: None,
                      'dict': {"sub": 1},
                      "list": [1, 2, 3]}

        # Dump it
        serialized = dump(dictionary)
        # Reload it
        deserialized = load(serialized)

        self.assertDictEqual(deserialized, dictionary)
    def test_object(self):
        """
        Tests dump & load of a custom type
        """
        types = {Bean: ('public', '_protected', '_Bean__private'),
                 InheritanceBean: ('public', '_protected', 'first', '_second'),
                 SlotBean: ('public', '_protected'),
                 InheritanceSlotBean: ('public', '_protected',
                                       'first', '_second'),
                 SecondInheritanceSlotBean: ('public', '_protected',
                                             'first', '_second',
                                             'third', '_fourth'), }

        for clazz, fields in types.items():
            # Prepare the bean
            data = clazz()

            # Dump it...
            serialized = dump(data)

            # Check serialized content
            self.assertIn('__jsonclass__', serialized)
            for field in fields:
                self.assertIn(field, serialized)

            # Check class name
            self.assertEqual(serialized['__jsonclass__'][0],
                             '{0}.{1}'.format(clazz.__module__,
                                              clazz.__name__))

            # Reload it
            deserialized = load(serialized)

            # Dictionary is left as-is
            self.assertIn('__jsonclass__', serialized,
                          "Serialized dictionary has been modified")
            self.assertFalse(hasattr(deserialized, '__jsonclass__'),
                             "The deserialized bean shouldn't have a "
                             "__jsonclass__ attribute")

            # Check deserialized value
            self.assertIs(type(deserialized), type(data))
            self.assertEqual(deserialized, data,
                             "Source and deserialized bean are not equal")
    def test_primitive(self):
        """
        Tests dump & load of primitive types
        """
        for value in (42, 42.12, "string", True, False, None):
            # Dump..
            serialized = dump(value)
            # Reload...
            deserialized = load(serialized)

            self.assertIs(type(serialized), type(value),
                          "Type changed during serialization")
            self.assertIs(type(deserialized), type(value),
                          "Type changed during deserialization")

            self.assertEqual(serialized, value,
                             "Value changed during serialization")
            self.assertEqual(deserialized, value,
                             "Value changed during deserialization")
Exemple #14
0
    def test_dictionary(self):
        """
        Tests dump & load of dictionaries
        """
        dictionary = {
            "int": 42,
            "float": 42.2,
            None: "string",
            True: False,
            42.1: None,
            "dict": {"sub": 1},
            "list": [1, 2, 3],
        }

        # Dump it
        serialized = dump(dictionary)
        # Reload it
        deserialized = load(serialized)

        self.assertDictEqual(deserialized, dictionary)
    def test_iterable(self):
        """
        Tests dump & load of iterable types
        """
        tuple_values = (42, 42.12, "string", True, False, None)
        list_values = list(tuple_values)
        set_values = set(tuple_values)
        frozen_values = frozenset(tuple_values)

        for iterable in (tuple_values, list_values, set_values, frozen_values):
            # Dump...
            serialized = dump(iterable)
            # Reload...
            deserialized = load(serialized)

            self.assertIs(type(serialized), list,
                          "Dumped iterable should be a list")
            self.assertIs(type(deserialized), list,
                          "Loaded iterable should be a list")

            # Check content
            self.assertCountEqual(deserialized, tuple_values,
                                  "Values order changed")
Exemple #16
0
def dump(params=None, methodname=None, rpcid=None, version=None,
         is_response=None, is_notify=None, config=jsonrpclib.config.DEFAULT):
    """
    Prepares a JSON-RPC dictionary (request, notification, response or error)

    :param params: Method parameters (if a method name is given) or a Fault
    :param methodname: Method name
    :param rpcid: Request ID
    :param version: JSON-RPC version
    :param is_response: If True, this is a response dictionary
    :param is_notify: If True, this is a notification request
    :param config: A JSONRPClib Config instance
    :return: A JSON-RPC dictionary
    """
    # Default version
    if not version:
        version = config.version

    if not is_response and params is None:
        params = []

    # Validate method name and parameters
    valid_params = [utils.TupleType, utils.ListType, utils.DictType, Fault]
    if is_response:
        valid_params.append(type(None))

    if isinstance(methodname, utils.STRING_TYPES) and \
            not isinstance(params, tuple(valid_params)):
        """
        If a method, and params are not in a listish or a Fault,
        error out.
        """
        raise TypeError("Params must be a dict, list, tuple "
                        "or Fault instance.")

    # Prepares the JSON-RPC content
    payload = Payload(rpcid=rpcid, version=version)

    if isinstance(params, Fault):
        # Prepare an error dictionary
        # pylint: disable=E1103
        return payload.error(params.faultCode, params.faultString, params.data)

    if not isinstance(methodname, utils.STRING_TYPES) and not is_response:
        # Neither a request nor a response
        raise ValueError('Method name must be a string, or is_response '
                         'must be set to True.')

    if config.use_jsonclass:
        # Use jsonclass to convert the parameters
        params = jsonclass.dump(params, config=config)

    if is_response:
        # Prepare a response dictionary
        if rpcid is None:
            # A response must have a request ID
            raise ValueError('A method response must have an rpcid.')
        return payload.response(params)

    if is_notify:
        # Prepare a notification dictionary
        return payload.notify(methodname, params)
    else:
        # Prepare a method call dictionary
        return payload.request(methodname, params)