I am trying out marshmallow
for serializing my data objects, because even though just writing out json dicts is really damn easy, for some reason everyone thinks it's more pythonic to use a package.
Problem is, it doesn't work the way it's advertised. The Str()
field is supposed to make a string from an attribute of the same name; the Function()
field is required to perform code execution. I don't think code execution should be required here, but Str()
is not working but Function()
is.
>>> q.origin
'local.qdb'
>>> from marshmallow import Schema, fields
>>> class StrSchema(Schema):
origin = fields.Str()
>>> StrSchema().dump(q)
MarshalResult(data={'origin': ''}, errors={})
>>> class FunctionSchema(Schema):
origin = fields.Function(lambda x: x.origin)
>>> FunctionSchema().dump(q)
MarshalResult(data={'origin': 'local.qdb'}, errors={})
Am I missing something? q
here is a complicated object, but it has an _origin
attribute and an origin
property that just returns the attribute. When I just create a dummy object that has those characteristics, it does not demonstrate the problem. There is no trickery in the origin
property of q
so I don't know what's wrong. But I'd appreciate any hints.
I found the answer: it is in the utils
file, in the function _get_value_for_key
:
def _get_value_for_key(key, obj, default):
try:
return obj[key]
except (KeyError, AttributeError, IndexError, TypeError):
try:
attr = getattr(obj, key)
return attr() if callable(attr) else attr
except AttributeError:
return default
return default
Basically, Marshmallow tries to __getitem__
before it tries getattr
; my object was returning empty on __getitem__
rather than raising a key error.
This is probably a documentation error.