marshmalling.Unmarshaller seems to ignore None data and don't try to validate passed data, even if there is required fields.
What the point having a validation library if we have to validate ourselves the "basic" case of None data?
Just asking the question, because it really doesn't seems logical to me (and because I had to handle myself this issue in my own code...)
required=True will make your field invalid if the input is _missing_. None is considered an input, so
MySchema().load({'required_field': None})
will validate.
If you do not want to allow None, set allow_none=False on the field.
from marshmallow import Schema, fields
class MySchema(Schema):
required_field = fields.Field(allow_none=False, required=False)
schema = MySchema()
print(schema.validate({'required_field': None}))
# {'required_field': ['Field may not be null.']}
Actually, the problem I had is when the whole loaded data is None, like:
MySchema().load(None) # Output (None, {})
load expects to receive dicts only; your code should ensure that load is always passed a dict. I suppose you could also do this in a pre_load method.
So I have to validate the data before passing it to a data validation library?
Schema#load and Schema#validate responsibility is to validate dict data, by default. None, False, numbers, as well as arbitrary complex objects, are outside their API boundary.
As mentioned above, you can use pre_load to preprocess inputs before they are validated.
from marshmallow import Schema, fields, pre_load
class MySchema(Schema):
required_field = fields.Field(required=True)
@pre_load
def ensure_dict(self, data):
return data or {}
schema = MySchema()
print(schema.validate(None))
# {'required_field': ['Missing data for required field']}
This just caught me out. My data argument to load was from a HTTP request's json dict, which was None when I forgot to use application/json as the Content-Type and validation was not happening.
I have not seen this behavior described in the docs, perhaps it should be? :)
There's this section of the docs: https://marshmallow.readthedocs.org/en/latest/quickstart.html#deserializing-objects-loading
The opposite of the dump method is the load method, which deserializes an input dictionary to an application-level data structure.
The API ref for load also specifies that the data argument is a dict: https://marshmallow.readthedocs.org/en/latest/api_reference.html#marshmallow.Schema.load .
I welcome any suggestions for making this clearer. Send a PR if you're feeling generous! =)