Marshmallow: Confused by fields.Function(serialize=f) behavior

Created on 5 Feb 2020  ·  2Comments  ·  Source: marshmallow-code/marshmallow

(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.

question

Most helpful comment

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.

All 2 comments

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.

Was this page helpful?
0 / 5 - 0 ratings