You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've faced this issue, when a schema has a field with name same as builtin dict's has attribute:
frommarshmallowimportfields, SchemaclassMyNestedSchema(Schema):
update=fields.Boolean(required=False)
classMySchema(Schema):
data=fields.Nested(MyNestedSchema)
classMyObj:
def__init__(self):
self.data= {
# NOT passing a value, so it's missing# 'update': True,
}
defmain():
obj=MyObj()
data=MySchema().dump(obj)
print(data)
if__name__=='__main__':
main()
Fails with this:
Traceback (most recent call last):
File "/home/khorenyan/.PyCharm2019.2/config/scratches/scratch_42.py", line 40, in <module>
main()
File "/home/khorenyan/.PyCharm2019.2/config/scratches/scratch_42.py", line 35, in main
data = MySchema().dump(obj)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/schema.py", line 556, in dump
result = self._serialize(processed_obj, many=many)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/schema.py", line 520, in _serialize
value = field_obj.serialize(attr_name, obj, accessor=self.get_attribute)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/fields.py", line 311, in serialize
return self._serialize(value, attr, obj, **kwargs)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/fields.py", line 566, in _serialize
return schema.dump(nested_obj, many=many)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/schema.py", line 556, in dump
result = self._serialize(processed_obj, many=many)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/schema.py", line 520, in _serialize
value = field_obj.serialize(attr_name, obj, accessor=self.get_attribute)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/fields.py", line 311, in serialize
return self._serialize(value, attr, obj, **kwargs)
File "/home/khorenyan/projs/marshmallow/src/marshmallow/fields.py", line 1103, in _serialize
elif value in self.truthy:
TypeError: unhashable type: 'dict'
It happens this way:
When being serialized, object is passed to the marshmallow.utils._get_value_for_key
because of the missing update field in data on the line obj[key] the KeyError exception is raised
and on the next line the getattr(obj, key, default) is returned
If the key is not found here, it returns default, so if my field is 'update_' or 'qwerty', it works as expected -- the result is returned and it's {'data': {}}
But the 'update' matches the builtin dict's attribute (method) so it's returned. And that's not expected at all.
Of course, I could override the get_attribute method in MyNestedSchema this way:
I thought about checking if the getattr(obj, key, default) expression returns a method of a builtin's object, or checking a key to be one of the builtin's attrs, for example:
I'm not sure if that's a proper way to do this check. Maybe we need to check even for isinstance instead of the object's type, but here's my current solution.
@deckar01 suggested discussing implementing something like schema.dump(obj, from_obj=dict)
The text was updated successfully, but these errors were encountered:
Referring the PR #1557
I've faced this issue, when a schema has a field with name same as builtin dict's has attribute:
Fails with this:
It happens this way:
marshmallow.utils._get_value_for_key
update
field in data on the lineobj[key]
theKeyError
exception is raisedgetattr(obj, key, default)
is returnedIf the
key
is not found here, it returns default, so if my field is'update_'
or'qwerty'
, it works as expected -- the result is returned and it's{'data': {}}
But the
'update'
matches the builtin dict's attribute (method) so it's returned. And that's not expected at all.Of course, I could override the
get_attribute
method inMyNestedSchema
this way:But I think, that needs to be fixed.
I thought about checking if the
getattr(obj, key, default)
expression returns a method of a builtin's object, or checking a key to be one of the builtin's attrs, for example:I'm not sure if that's a proper way to do this check. Maybe we need to check even for
isinstance
instead of the object's type, but here's my current solution.@deckar01 suggested discussing implementing something like
schema.dump(obj, from_obj=dict)
The text was updated successfully, but these errors were encountered: