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)
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)
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
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