예제 #1
0
 def format(self, value):
     try:
         if value is None:
             return text_type(utils.float_to_decimal(float(self.default)))
         return text_type(utils.float_to_decimal(float(value)))
     except ValueError as ve:
         raise MarshallingError(ve)
예제 #2
0
 def format(self, value):
     try:
         if value is None:
             return text_type(utils.float_to_decimal(float(self.default)))
         return text_type(utils.float_to_decimal(float(value)))
     except ValueError as ve:
         raise MarshallingError(ve)
예제 #3
0
 def __init__(self, choices, labels=None, error=None):
     self.choices = choices
     self.choices_text = ', '.join(
         text_type(choice) for choice in self.choices)
     self.labels = labels if labels is not None else []
     self.labels_text = ', '.join(text_type(label) for label in self.labels)
     self.error = error or self.default_message
예제 #4
0
 def _validated(self, value):
     """Format ``value`` or raise ``exception_class`` if an error occurs."""
     try:
         if value is None:
             return self.default
         return text_type(utils.float_to_decimal(float(value)))
     except ValueError as ve:
         raise ValidationError(text_type(ve))
예제 #5
0
    def _serialize(self, value, attr, obj):
        if isinstance(value, text_type) or value is None:
            return value

        elif isinstance(value, binary_type):
            for codec in self.codecs:
                try:
                    return text_type(value, codec)
                except UnicodeDecodeError:
                    pass
            raise ValueError("Could not decode {value} to unicode"
                             " with the given codecs: {codecs}".format(
                                 value=value, codecs=self.codecs))
        else:
            return text_type(value)
예제 #6
0
    def marshal(self, data, fields_dict, many=False):
        """Takes raw data (a dict, list, or other object) and a dict of
        fields to output and filters the data based on those fields.

        :param data: The actual object(s) from which the fields are taken from
        :param dict fields: A dict whose keys will make up the final serialized
                       response output.
        :param bool many: Set to ``True`` if ``data`` is a collection object
                        that is iterable.
        :returns: An OrderedDict of the marshalled data
        """
        if many and data is not None:
            return [self.marshal(d, fields_dict, many=False) for d in data]
        items = []
        for attr_name, field_obj in iteritems(fields_dict):
            key = self.prefix + attr_name
            try:
                item = (key, field_obj.output(attr_name, data))
            except MarshallingError as err:  # Store errors
                if self.strict:
                    raise err
                self.errors[key] = text_type(err)
                item = (key, None)
            except TypeError:
                # field declared as a class, not an instance
                if isinstance(field_obj, type) and \
                    issubclass(field_obj, FieldABC):
                    msg = ('Field for "{0}" must be declared as a '
                           "Field instance, not a class. "
                           'Did you mean "fields.{1}()"?'.format(
                               attr_name, field_obj.__name__))
                    raise TypeError(msg)
                raise
            items.append(item)
        return OrderedDict(items)
예제 #7
0
    def marshal(self, data, fields_dict, many=False):
        """Takes raw data (a dict, list, or other object) and a dict of
        fields to output and filters the data based on those fields.

        :param data: The actual object(s) from which the fields are taken from
        :param dict fields: A dict whose keys will make up the final serialized
                       response output.
        :param bool many: Set to ``True`` if ``data`` is a collection object
                        that is iterable.
        :returns: An OrderedDict of the marshalled data
        """
        if many and data is not None:
            return [self.marshal(d, fields_dict, many=False) for d in data]
        items = []
        for attr_name, field_obj in iteritems(fields_dict):
            key = self.prefix + attr_name
            try:
                item = (key, field_obj.output(attr_name, data))
            except MarshallingError as err:  # Store errors
                if self.strict:
                    raise err
                self.errors[key] = text_type(err)
                item = (key, None)
            except TypeError:
                # field declared as a class, not an instance
                if isinstance(field_obj, type) and \
                    issubclass(field_obj, FieldABC):
                    msg = ('Field for "{0}" must be declared as a '
                                    "Field instance, not a class. "
                                    'Did you mean "fields.{1}()"?'
                                    .format(attr_name, field_obj.__name__))
                    raise TypeError(msg)
                raise
            items.append(item)
        return OrderedDict(items)
예제 #8
0
    def marshal(self, data, fields_dict):
        """Takes the data (a dict, list, or object) and a dict of fields.
        Stores any errors that occur.

        :param data: The actual object(s) from which the fields are taken from
        :param dict fields_dict: A dict whose keys will make up the final serialized
                       response output
        """
        if utils.is_collection(data):
            return [self.marshal(d, fields_dict) for d in data]
        items = []
        for attr_name, field_obj in iteritems(fields_dict):
            key = self.prefix + attr_name
            try:
                if isinstance(field_obj, dict):
                    item = (key, self.marshal(data, field_obj))
                else:
                    try:
                        item = (key, field_obj.output(attr_name, data))
                    except TypeError:
                        # field declared as a class, not an instance
                        if issubclass(field_obj, base.FieldABC):
                            msg = ('Field for "{0}" must be declared as a '
                                            "Field instance, not a class. "
                                            'Did you mean "fields.{1}()"?'
                                            .format(attr_name, field_obj.__name__))
                            raise TypeError(msg)
                        raise
            except exceptions.MarshallingError as err:  # Store errors
                if self.strict or self.opts.strict:
                    raise err
                self.errors[key] = text_type(err)
                item = (key, None)
            items.append(item)
        return OrderedDict(items)
예제 #9
0
 def run_validator(self, validator_func, output,
         original_data, fields_dict, index=None,
         many=False, pass_original=False):
     try:
         if pass_original:  # Pass original, raw data (before unmarshalling)
             res = validator_func(output, original_data)
         else:
             res = validator_func(output)
         if res is False:
             raise ValidationError(self.default_schema_validation_error)
     except ValidationError as err:
         errors = self.get_errors(index=index)
         # Store or reraise errors
         if err.field_names:
             field_names = err.field_names
             field_objs = [fields_dict[each] if each in fields_dict else None
                           for each in field_names]
         else:
             field_names = [SCHEMA]
             field_objs = []
         self.error_field_names = field_names
         self.error_fields = field_objs
         for field_name in field_names:
             if isinstance(err.messages, (list, tuple)):
                 # self.errors[field_name] may be a dict if schemas are nested
                 if isinstance(errors.get(field_name), dict):
                     errors[field_name].setdefault(
                         SCHEMA, []
                     ).extend(err.messages)
                 else:
                     errors.setdefault(field_name, []).extend(err.messages)
             elif isinstance(err.messages, dict):
                 errors.setdefault(field_name, []).append(err.messages)
             else:
                 errors.setdefault(field_name, []).append(text_type(err))
예제 #10
0
 def _validated(self, value):
     """Format the value or raise a :exc:`ValidationError` if an error occurs."""
     try:
         return self._format_num(value)
     except (TypeError, ValueError) as err:
         raise ValidationError(
             getattr(self, 'error', None) or text_type(err))
예제 #11
0
 def __init__(self, src_str, *args, **kwargs):
     warnings.warn(
         'FormattedString is deprecated and will be removed in marshmallow 3. '
         'Use a Method or Function field instead.',
         RemovedInMarshmallow3Warning)
     Field.__init__(self, *args, **kwargs)
     self.src_str = text_type(src_str)
예제 #12
0
 def _validated(self, value):
     """Format the value or raise ``exception_class`` if an error occurs."""
     if value is None:
         return self.default
     try:
         return self._format_num(value)
     except (TypeError, ValueError, decimal.InvalidOperation) as err:
         raise ValidationError(getattr(self, 'error', None) or text_type(err))
예제 #13
0
 def __init__(self, underlying_exception):
     if isinstance(underlying_exception, Exception):
         self.underlying_exception = underlying_exception
     else:
         self.underlying_exception = None
     super(_WrappingException, self).__init__(
         text_type(underlying_exception)
     )
예제 #14
0
 def format(self, value):
     try:
         dvalue = utils.float_to_decimal(float(value))
     except ValueError as ve:
         raise MarshallingError(ve)
     if not dvalue.is_normal() and dvalue != ZERO:
         raise MarshallingError('Invalid Fixed precision number.')
     return text_type(dvalue.quantize(self.precision, rounding=ROUND_HALF_EVEN))
예제 #15
0
 def _deserialize(self, value):
     if not value:
         return False
     try:
         value_str = text_type(value)
     except TypeError as error:
         raise ValidationError(text_type(error))
     if value_str in self.falsy:
         return False
     elif self.truthy:
         if value_str in self.truthy:
             return True
         else:
             raise ValidationError(
                 '{0!r} is not in {1} nor {2}'.format(
                     value_str, self.truthy, self.falsy
                 ))
     return True
예제 #16
0
 def handle_invalid_json_error(self, error, req, *args, **kwargs):
     messages = {"json": ["Invalid JSON body."]}
     response = exception_response(400,
                                   detail=text_type(messages),
                                   content_type="application/json")
     body = json.dumps(messages)
     response.body = body.encode("utf-8") if isinstance(body,
                                                        text_type) else body
     raise response
예제 #17
0
 def __init__(self, underlying_exception, field=None, field_name=None):
     if isinstance(underlying_exception, Exception):
         self.underlying_exception = underlying_exception
     else:
         self.underlying_exception = None
     self.field = field
     self.field_name = field_name
     super(_WrappingException, self).__init__(
         text_type(underlying_exception)
     )
예제 #18
0
def get_pk_from_identity(obj):
    """Get primary key for `obj`. If `obj` has a compound primary key,
    return a string of keys separated by ``":"``. This is the default keygetter for
    used by `ModelSchema <marshmallow_sqlalchemy.ModelSchema>`.
    """
    _, key = identity_key(instance=obj)
    if len(key) == 1:
        return key[0]
    else:  # Compund primary key
        return ':'.join(text_type(x) for x in key)
예제 #19
0
 def _deserialize(self, value):
     if not value:
         return False
     try:
         value_str = text_type(value)
     except TypeError as error:
         msg = getattr(self, 'error', None) or text_type(error)
         raise ValidationError(msg)
     if value_str in self.falsy:
         return False
     elif self.truthy:
         if value_str in self.truthy:
             return True
         else:
             default_message = '{0!r} is not in {1} nor {2}'.format(
                 value_str, self.truthy, self.falsy)
             msg = getattr(self, 'error', None) or default_message
             raise ValidationError(msg)
     return True
예제 #20
0
 def _serialize(self, value, attr, obj):
     if value:
         self.dateformat = self.dateformat or self.DEFAULT_FORMAT
         format_func = self.DATEFORMAT_SERIALIZATION_FUNCS.get(self.dateformat, None)
         if format_func:
             try:
                 return format_func(value, localtime=self.localtime)
             except (AttributeError, ValueError) as err:
                 raise ValidationError(getattr(self, 'error', None) or text_type(err))
         else:
             return value.strftime(self.dateformat)
예제 #21
0
 def get_is_old(self, obj):
     if obj is None:
         return missing
     if isinstance(obj, dict):
         age = obj.get('age')
     else:
         age = obj.age
     try:
         return age > 80
     except TypeError as te:
         raise ValidationError(text_type(te))
예제 #22
0
 def _validated(self, value):
     if value is None:
         return None
     try:
         dvalue = utils.float_to_decimal(float(value))
     except (TypeError, ValueError) as err:
         raise ValidationError(getattr(self, 'error', None) or text_type(err))
     if not dvalue.is_normal() and dvalue != utils.ZERO_DECIMAL:
         raise ValidationError(
             getattr(self, 'error', None) or 'Invalid Fixed precision number.'
         )
     return utils.decimal_to_fixed(dvalue, self.precision)
예제 #23
0
def _call_and_store(getter_func, data, field_name, field_obj, errors_dict,
               exception_class, strict=False):
    """Helper method for DRYing up logic in the :meth:`Marshaller.serialize` and
    :meth:`UnMarshaller.deserialize` methods. Call ``getter_func`` with ``data`` as its
    argument, and store any errors of type ``exception_class`` in ``error_dict``.

    :param callable getter_func: Function for getting the serialized/deserialized
        value from ``data``.
    :param data: The data passed to ``getter_func``.
    :param str field_name: Field name.
    :param FieldABC field_obj: Field object that performs the
        serialization/deserialization behavior.
    :param dict errors_dict: Dictionary to store errors on.
    :param type exception_class: Exception class that will be caught during
        serialization/deserialization. Errors of this type will be stored
        in ``errors_dict``.
    """
    try:
        value = getter_func(data)
    except RegistryError:
        raise
    except exception_class as err:  # Store errors
        if strict:
            err.field = field_obj
            err.field_name = field_name
            raise err
        # Warning: Mutation!
        if (hasattr(err, 'underlying_exception') and
                isinstance(err.underlying_exception, ValidationError)):
            validation_error = err.underlying_exception
            if isinstance(validation_error.messages, dict):
                errors_dict[field_name] = validation_error.messages
            else:
                errors_dict.setdefault(field_name, []).extend(validation_error.messages)
        else:
            errors_dict.setdefault(field_name, []).append(text_type(err))
        value = None
    except TypeError:
        # field declared as a class, not an instance
        if (isinstance(field_obj, type) and
                issubclass(field_obj, FieldABC)):
            msg = ('Field for "{0}" must be declared as a '
                            'Field instance, not a class. '
                            'Did you mean "fields.{1}()"?'
                            .format(field_name, field_obj.__name__))
            raise TypeError(msg)
        raise
    return value
예제 #24
0
 def _validate(self,
               validators,
               output,
               raw_data,
               fields_dict,
               strict=False):
     """Perform schema-level validation. Stores errors if ``strict`` is `False`.
     """
     for validator_func in validators:
         try:
             func_args = utils.get_func_args(validator_func)
             if len(func_args) < 3:
                 res = validator_func(output)
             else:
                 res = validator_func(output, raw_data)
             if res is False:
                 func_name = utils.get_func_name(validator_func)
                 raise ValidationError(
                     'Schema validator {0}({1}) is False'.format(
                         func_name, dict(output)))
         except ValidationError as err:
             # Store or reraise errors
             if err.field_names:
                 field_names = err.field_names
                 field_objs = [fields_dict[each] for each in field_names]
             else:
                 field_names = ['_schema']
                 field_objs = []
             for field_name in field_names:
                 if isinstance(err.messages, (list, tuple)):
                     # self.errors[field_name] may be a dict if schemas are nested
                     if isinstance(self.errors.get(field_name), dict):
                         self.errors[field_name].setdefault(
                             '_schema', []).extend(err.messages)
                     else:
                         self.errors.setdefault(field_name,
                                                []).extend(err.messages)
                 elif isinstance(err.messages, dict):
                     self.errors.setdefault(field_name,
                                            []).append(err.messages)
                 else:
                     self.errors.setdefault(field_name,
                                            []).append(text_type(err))
             if strict:
                 raise ValidationError(self.errors,
                                       fields=field_objs,
                                       field_names=field_names)
     return output
예제 #25
0
 def handle_error(self, error, req, schema, error_status_code,
                  error_headers):
     """Handles errors during parsing. Aborts the current HTTP request and
     responds with a 400 error.
     """
     status_code = error_status_code or self.DEFAULT_VALIDATION_STATUS
     response = exception_response(
         status_code,
         detail=text_type(error),
         headers=error_headers,
         content_type="application/json",
     )
     body = json.dumps(error.messages)
     response.body = body.encode("utf-8") if isinstance(body,
                                                        text_type) else body
     raise response
예제 #26
0
    def test_boolean_field_deserialization_with_custom_truthy_values_invalid(
            self, in_val):
        class MyBoolean(fields.Boolean):
            truthy = set(['yep'])

        field = MyBoolean()
        with pytest.raises(ValidationError) as excinfo:
            field.deserialize(in_val)
        expected_msg = '{0!r} is not in {1} nor {2}'.format(
            text_type(in_val), field.truthy, field.falsy)
        assert str(excinfo.value.args[0]) == expected_msg

        field2 = MyBoolean(error='bad input')
        with pytest.raises(ValidationError) as excinfo:
            field2.deserialize(in_val)
        assert str(excinfo.value.args[0]) == 'bad input'
예제 #27
0
 def run_validator(self,
                   validator_func,
                   output,
                   original_data,
                   fields_dict,
                   index=None,
                   many=False,
                   pass_original=False):
     try:
         if pass_original:  # Pass original, raw data (before unmarshalling)
             res = validator_func(output, original_data)
         else:
             res = validator_func(output)
         if res is False:
             raise ValidationError(self.default_schema_validation_error)
     except ValidationError as err:
         errors = self.get_errors(index=index)
         # Store or reraise errors
         if err.field_names:
             field_names = err.field_names
             field_objs = [
                 fields_dict[each] if each in fields_dict else None
                 for each in field_names
             ]
         else:
             field_names = [SCHEMA]
             field_objs = []
         self.error_field_names = field_names
         self.error_fields = field_objs
         for field_name in field_names:
             if isinstance(err.messages, (list, tuple)):
                 # self.errors[field_name] may be a dict if schemas are nested
                 if isinstance(errors.get(field_name), dict):
                     errors[field_name].setdefault(SCHEMA,
                                                   []).extend(err.messages)
                 else:
                     errors.setdefault(field_name, []).extend(err.messages)
             elif isinstance(err.messages, dict):
                 errors.setdefault(field_name, []).append(err.messages)
             else:
                 errors.setdefault(field_name, []).append(text_type(err))
         raise ValidationError(self.errors,
                               fields=field_objs,
                               field_names=field_names,
                               data=output)
예제 #28
0
 def _validate(self, validators, output, raw_data, fields_dict, strict=False):
     """Perform schema-level validation. Stores errors if ``strict`` is `False`.
     """
     for validator_func in validators:
         try:
             func_args = utils.get_func_args(validator_func)
             if len(func_args) < 3:
                 res = validator_func(output)
             else:
                 res = validator_func(output, raw_data)
             if res is False:
                 func_name = utils.get_func_name(validator_func)
                 raise ValidationError('Schema validator {0}({1}) is False'.format(
                     func_name, dict(output)
                 ))
         except ValidationError as err:
             # Store or reraise errors
             if err.field_names:
                 field_names = err.field_names
                 field_objs = [fields_dict[each] for each in field_names]
             else:
                 field_names = ['_schema']
                 field_objs = []
             for field_name in field_names:
                 if isinstance(err.messages, (list, tuple)):
                     # self.errors[field_name] may be a dict if schemas are nested
                     if isinstance(self.errors.get(field_name), dict):
                         self.errors[field_name].setdefault(
                             '_schema', []
                         ).extend(err.messages)
                     else:
                         self.errors.setdefault(field_name, []).extend(err.messages)
                 elif isinstance(err.messages, dict):
                     self.errors.setdefault(field_name, []).append(err.messages)
                 else:
                     self.errors.setdefault(field_name, []).append(text_type(err))
             if strict:
                 raise ValidationError(
                     self.errors,
                     fields=field_objs,
                     field_names=field_names
                 )
     return output
예제 #29
0
 def _validate(self, validators, output, fields_dict, strict=False):
     """Perform schema-level validation. Stores errors if ``strict`` is `False`.
     """
     for validator_func in validators:
         try:
             if validator_func(output) is False:
                 func_name = utils.get_func_name(validator_func)
                 raise ValidationError(u'Schema validator {0}({1}) is False'.format(
                     func_name, dict(output)
                 ))
         except ValidationError as err:
             # Store or reraise errors
             if err.field:
                 field_name = err.field
                 field_obj = fields_dict[field_name]
             else:
                 field_name = '_schema'
                 field_obj = None
             if strict:
                 raise UnmarshallingError(err, field=field_obj, field_name=field_name)
             self.errors.setdefault(field_name, []).append(text_type(err))
     return output
예제 #30
0
 def __init__(self, iterable, error=None):
     self.iterable = iterable
     self.values_text = ', '.join(text_type(each) for each in self.iterable)
     self.error = error or self.default_message
예제 #31
0
 def test_arbitrary_field_deserialization(self):
     field = fields.Arbitrary()
     expected = text_type(utils.float_to_decimal(float(42)))
     assert field.deserialize('42') == expected
예제 #32
0
 def __init__(self, iterable, error=None):
     self.iterable = iterable
     self.values_text = ', '.join(text_type(each) for each in self.iterable)
     self.error = error or self.default_message
예제 #33
0
def ensure_text_type(val):
    if isinstance(val, binary_type):
        val = val.decode('utf-8')
    return text_type(val)
예제 #34
0
 def __init__(self, src_str, *args, **kwargs):
     Field.__init__(self, *args, **kwargs)
     self.src_str = text_type(src_str)
예제 #35
0
 def __init__(self, choices, labels=None, error=None):
     self.choices = choices
     self.choices_text = ', '.join(text_type(choice) for choice in self.choices)
     self.labels = labels if labels is not None else []
     self.labels_text = ', '.join(text_type(label) for label in self.labels)
     self.error = error or self.default_message
예제 #36
0
 def handle_error(self, error):
     """Handles errors during parsing. Aborts the current HTTP request and
     responds with a 400 error.
     """
     status_code = getattr(error, "status_code", 400)
     raise exception_response(status_code, detail=text_type(error))
예제 #37
0
 def test_arbitrary_field(self, user):
     field = fields.Arbitrary()
     user.age = 12.3
     result = field.serialize('age', user)
     assert result == text_type(utils.float_to_decimal(user.age))
예제 #38
0
 def test_arbitrary_field_deserialization(self):
     field = fields.Arbitrary()
     expected = text_type(utils.float_to_decimal(float(42)))
     assert field.deserialize('42') == expected
예제 #39
0
 def format(self, value):
     try:
         return text_type(value)
     except ValueError as ve:
         raise MarshallingError(self.error or ve)
예제 #40
0
 def validator(value):
     try:
         converter(value)
     except Exception as e:
         raise ValidationError(compat.text_type(e))
예제 #41
0
 def _format_error(self, value):
     value_text = ', '.join(text_type(val) for val in value)
     return super(ContainsOnly, self)._format_error(value_text)
예제 #42
0
 def handle_error(self, error):
     """Handles errors during parsing. Aborts the current HTTP request and
     responds with a 400 error.
     """
     status_code = getattr(error, 'status_code', 422)
     raise exception_response(status_code, detail=text_type(error))
예제 #43
0
def decimal_to_fixed(value, precision):
    """Convert a `Decimal` to a fixed-precision number as a string."""
    return text_type(value.quantize(precision, rounding=ROUND_HALF_EVEN))
예제 #44
0
def ensure_text_type(val):
    if isinstance(val, binary_type):
        val = val.decode('utf-8')
    return text_type(val)
예제 #45
0
파일: fields.py 프로젝트: synic/marshmallow
 def __init__(self, src_str, *args, **kwargs):
     Field.__init__(self, *args, **kwargs)
     self.src_str = text_type(src_str)
예제 #46
0
def decimal_to_fixed(value, precision):
    """Convert a `Decimal` to a fixed-precision number as a string."""
    return text_type(value.quantize(precision, rounding=ROUND_HALF_EVEN))
예제 #47
0
 def _format_error(self, value):
     value_text = ', '.join(text_type(val) for val in value)
     return super(ContainsOnly, self)._format_error(value_text)
예제 #48
0
 def __init__(self, src_str):
     super(FormattedString, self).__init__()
     self.src_str = text_type(src_str)