marshmallow-oneofschema
marshmallow-oneofschema copied to clipboard
_dump should raise errors instead of returning them
The Error
If the default get_obj_type
is used (i.e. when the subclass does not overwrite the get_obj_type
method), then the dumping of the schema does not raise an error when encountering an unknown type. Instead, the error gets dumped into the serialization outputs.
It looks like _dump
returns an error tuple on unexpected behaviour:
https://github.com/marshmallow-code/marshmallow-oneofschema/blob/master/marshmallow_oneofschema/one_of_schema.py#L99
... but dump
expects Exceptions to be thrown:
https://github.com/marshmallow-code/marshmallow-oneofschema/blob/master/marshmallow_oneofschema/one_of_schema.py#L77
Minimal example
# minimal_example.py
import marshmallow
import marshmallow.fields
from marshmallow_oneofschema import OneOfSchema
class Foo(object):
def __init__(self, foo):
self.foo = foo
class Bar(object):
def __init__(self, bar):
self.bar = bar
class FooSchema(marshmallow.Schema):
foo = marshmallow.fields.String(required=True)
@marshmallow.post_load
def make_foo(self, data):
return Foo(**data)
class BarSchema(marshmallow.Schema):
bar = marshmallow.fields.Integer(required=True)
@marshmallow.post_load
def make_bar(self, data):
return Bar(**data)
class MyUberSchema(OneOfSchema):
type_schemas = {
'Foo': FooSchema
}
if __name__ == '__main__':
serialized = MyUberSchema().dump([
Foo(foo='hello'),
Bar(bar=123)],
many=True)
print(serialized)
~$ pip freeze | grep marshmallow
marshmallow==3.0.0b19
marshmallow-oneofschema==2.0.0b2
~$ python --version
Python 3.6.7 :: Anaconda, Inc.
~$ python minimal_example.py
[{'foo': 'hello', 'type': 'Foo'}, (None, {'_schema': 'Unsupported object type: Bar'})]
Feels like code written for marshmallow 2...
If everything is fine, dump
returns an ordered dict of the object, e.g. {"hello": "world"}
. If handling object type fails, it returns (None, {"_schema": "Unsupported object type: something"})
. How are we supposed to handle this? Why not just always raise ValidationError
?
I added a workaround for this to my subclass of OneOfSchema
but it's very ugly:
class MySchema(OneOfSchema):
def _dump(self, obj, *, update_fields=True, **kwargs):
res = super()._dump(obj, update_fields=update_fields, **kwargs)
if isinstance(res, tuple) and len(res) == 2 and res[0] is None and isinstance(res[1], dict):
error_dict = res[1]
field_name, message = list(error_dict.items())[0]
raise ValidationError(message=message, field_name=field_name)
return res
Any suggestions to make it better?