Beispiel #1
0
def test_format_to_tuple(value, expected_result, fails):
    if not fails:
        result = format_to_tuple(value)
        assert result == expected_result
    else:
        with pytest.raises(InvalidFormatError):
            result = format_to_tuple(value)
Beispiel #2
0
def get_default_serializer(class_attribute=None, format=None, value=None):
    """Retrieve the default ``on_serialize`` function that applies to the data
    type of ``class_attribute``.

    .. note::

      If ``class_attribute`` does not have a SQLAlchemy data type, then
      determines the data type based on ``value``.

    :param class_attribute: The class attribute whose default serializer will be
      returned. Defaults to :obj:`None <python:None>`.

    :param format: The format to which the value should be serialized. Accepts
      either: ``csv``, ``json``, ``yaml``, or ``dict``. Defaults to :obj:`None <python:None>`.
    :type format: :class:`str <python:str>`

    :param value: The class attribute's value.

    :returns: The default :term:`serializer function` to apply or :obj:`None <python:None>`
    :rtype: callable / :obj:`None <python:None>`

    :raises InvalidFormatError: if ``format`` is not a valid format type
    """
    format_to_tuple(format)
    format = format.lower()

    class_type_key = get_class_type_key(class_attribute, value)

    serializer_dict = DEFAULT_SERIALIZERS.get(class_type_key, None)

    if serializer_dict is None:
        return None

    return serializer_dict.get(format, None)
Beispiel #3
0
    def _get_deserialized_value(cls,
                                value,
                                format,
                                attribute,
                                config_set=None,
                                **kwargs):
        """Retrieve the value of ``attribute`` after applying the attribute's
        ``on_deserialize`` function for the format indicated by ``format``.

        :param value: The input value that was received when de-serializing.

        :param format: The format to which the value should be serialized. Accepts
          either: ``csv``, ``json``, ``yaml``, or ``dict``.
        :type format: :class:`str <python:str>`

        :param attribute: The name of the attribute that whose serialized value
          should be returned.
        :type attribute: :class:`str <python:str>`

        :param config_set: If not :obj:`None <python:None>`, the named configuration set
          whose configuration should be used to determine the deserialized value. Defaults
          to :obj:`None <python:None>`.
        :type config_set: :class:`str <python:str>` / :obj:`None <python:None>`

        :returns: The value returned by the attribute's ``on_serialize`` function
          for the indicated ``format``.

        :raises InvalidFormatError: if ``format`` is not ``csv``, ``json``, ``yaml``,
          or ``dict``.
        :raises ValueDeserializationError: if the ``on_deserialize`` function raises
          an exception
        """
        # pylint: disable=line-too-long

        from_csv, from_json, from_yaml, from_dict = format_to_tuple(format)

        try:
            supports_deserialization = cls.does_support_serialization(
                attribute,
                from_csv=from_csv,
                from_json=from_json,
                from_yaml=from_yaml,
                from_dict=from_dict,
                config_set=config_set)
        except UnsupportedSerializationError:
            supports_deserialization = False

        if inspect_.isclass(cls):
            class_name = str(cls)
            class_obj = cls
        else:
            class_name = str(type(cls))
            class_obj = cls.__class__

        if not supports_deserialization:
            raise UnsupportedDeserializationError(
                "%s attribute '%s' does not support de-serialization from '%s'" % \
                (class_name,
                 attribute,
                 format)
            )

        config = cls.get_attribute_serialization_config(attribute,
                                                        config_set=config_set)

        on_deserialize = config.on_deserialize[format]
        if on_deserialize is None:
            on_deserialize = get_default_deserializer(getattr(
                class_obj, config.name),
                                                      format=format)

        if on_deserialize is None:
            item = getattr(class_obj, config.name)
            class_resolver = getattr(getattr(item, 'property', None),
                                     'argument', None)
            if class_resolver:
                resolved_class = class_resolver()
            else:
                resolved_class = None
            if resolved_class:
                # pylint: disable=W0212
                if hasattr(
                        resolved_class,
                        'new_from_json') and format == 'json' and isinstance(
                            value, dict):
                    as_json = json.dumps(value)
                    return_value = resolved_class.new_from_json(
                        as_json, **kwargs)
                elif hasattr(
                        resolved_class,
                        'new_from_yaml') and format == 'yaml' and isinstance(
                            value, dict):
                    as_yaml = yaml.dump(value)
                    return_value = resolved_class.new_from_yaml(
                        value, **kwargs)
                elif hasattr(
                        resolved_class,
                        'new_from_dict') and format == 'dict' and isinstance(
                            value, dict):
                    return_value = resolved_class.new_from_dict(
                        value, **kwargs)
                else:
                    return_value = [
                        resolved_class(
                            **resolved_class._parse_dict(x, format, **kwargs))
                        for x in value
                    ]
                #pylint: enable=W0212
            else:
                return_value = value
        else:
            try:
                return_value = on_deserialize(value)
            except Exception:
                raise ValueDeserializationError(
                    "attribute '%s' failed de-serialization to format '%s'" %
                    (attribute, format))

        return return_value
Beispiel #4
0
    def _get_serialized_value(self, format, attribute, config_set=None):
        """Retrieve the value of ``attribute`` after applying the attribute's
        ``on_serialize`` function for the format indicated by ``format``.

        :param format: The format to which the value should be serialized. Accepts
          either: ``csv``, ``json``, ``yaml``, or ``dict``.
        :type format: :class:`str <python:str>`

        :param attribute: The name of the attribute that whose serialized value
          should be returned.
        :type attribute: :class:`str <python:str>`

        :param config_set: The name of the named configuration set whose configuration
          should be used to retrieve the serialized value. Defaults to
          :obj:`None <python:None>`.
        :type config_set: :class:`str <python:str>` / :obj:`None <python:None>`

        :returns: The value returned by the attribute's ``on_serialize`` function
          for the indicated ``format``.

        :raises InvalidFormatError: if ``format`` is not ``csv``, ``json``, ``yaml``,
          or ``dict``.
        :raises ValueSerializationError: if the ``on_serialize`` function raises
          an exception
        """
        # pylint: disable=line-too-long

        to_csv, to_json, to_yaml, to_dict = format_to_tuple(format)

        supports_serialization = self.does_support_serialization(
            attribute,
            to_csv=to_csv,
            to_json=to_json,
            to_yaml=to_yaml,
            to_dict=to_dict,
            config_set=config_set)
        if not supports_serialization:
            raise UnsupportedSerializationError(
                "%s attribute '%s' does not support serialization to '%s'" %
                (self.__class__, attribute, format))

        config = self.get_attribute_serialization_config(attribute,
                                                         config_set=config_set)

        on_serialize = config.on_serialize[format]
        if on_serialize is None:
            on_serialize = get_default_serializer(
                getattr(self.__class__, attribute),
                format=format,
                value=getattr(self, attribute, None))

        if on_serialize is None:
            if format == 'csv':
                return getattr(self, attribute, '')

            return getattr(self, attribute, None)

        try:
            return_value = on_serialize(getattr(self, attribute, None))
        except Exception:
            raise ValueSerializationError(
                "attribute '%s' failed serialization to format '%s'" %
                (attribute, format))

        return return_value