Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_dump should raise errors instead of returning them #48

Open
robbertvc opened this issue Jan 8, 2019 · 3 comments
Open

_dump should raise errors instead of returning them #48

robbertvc opened this issue Jan 8, 2019 · 3 comments

Comments

@robbertvc
Copy link

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'})]
@ThiefMaster
Copy link

Feels like code written for marshmallow 2...

@kamzil
Copy link

kamzil commented Feb 9, 2024

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?

@kamzil
Copy link

kamzil commented Feb 9, 2024

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants