(marshmallow 2.xx) (Yes, I do recognize that fields.DateTime is built for my example case. My questions below still holds though.)
I don't follow how the serialize=function kwarg is supposed to work for fields.Function. Digging around the code for _serialize, I found this comment which leads me to believe I don't understand the how this is supposed to be used:
def _serialize(self, value, attr, obj):
try:
return self._call_or_raise(self.serialize_func, obj, attr)
except AttributeError: # the object is not expected to have the attribute
pass
return missing_
# the object is not expected to have the attribute really? Then what should I do if I want to have a serialized version of an attribute?
Say I have this schema:
class SomeSchema(Schema):
created_at = fields.Function(
serialize=lambda value: value['created_at'].toisoformat(),
deserialize=lambda value: datetime.fromisoformat(value)
)
What can should the serialize function be passed if it isn't expected to be passed an object with the attribute? The following result from a load + dump is baffling to me:
In [2]: from datetime import datetime, timezone
In [3]: from upstreamapi.activities import SomeSchema
In [4]: d = SomeSchema().load({'created_at': datetime.now().isoformat()}).data
In [5]: d
Out[5]: {'created_at': datetime.datetime(2020, 2, 5, 9, 9, 50, 847165)}
In [6]: SomeSchema().dump(d)
Out[6]: MarshalResult(data={}, errors={})
The key point being that the data is missing a created_at field, even though it was present in the input to dump.
It looks like an AttributeError is being raised because toisoformat is not a method of datetime.datetime. It should work if you change it to isoformat.
Note: marshmallow 3 no longer swallows AttributeError, which makes bugs like this much easier to find.
That was it, thank you! Had one of those 'I'm losing my mind' experiences this morning with this.
Most helpful comment
It looks like an
AttributeErroris being raised becausetoisoformatis not a method ofdatetime.datetime. It should work if you change it toisoformat.Note: marshmallow 3 no longer swallows
AttributeError, which makes bugs like this much easier to find.