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

Error when passing custom parameter in Nested schema #2306

Open
qurram-zaheer opened this issue Sep 10, 2024 · 2 comments
Open

Error when passing custom parameter in Nested schema #2306

qurram-zaheer opened this issue Sep 10, 2024 · 2 comments

Comments

@qurram-zaheer
Copy link

qurram-zaheer commented Sep 10, 2024

Hello, I have 2 schemas set up something like this:

from marshmallow import Schema, fields, post_dump
from xyz.abc import CustomISODateTime


class SchemaA(Schema):
    ....
    field = fields.Dict(
        required=False,
        load_default={},
    ) # This dict will look like {..., 'string': 'abc'} 
    

    def __init__(self, *args, **kwargs):
        self.replace_field_with_string = (
            kwargs.pop('replace_field_with_string', False))
        super().__init__(*args, **kwargs)

    @post_dump
    def convert_field_to_string(self, data, **kwargs):
        if (self.replace_field_with_string and 'field' in data
            and isinstance(data['field'], dict)):
            data['field'] = data['field'].get('string', '')
        return data


class SchemaB(Schema):
    data = fields.List(
        fields.Nested(lambda: SchemaA(replace_field_with_string=True)),
        required=True,
        dump_only=True,
    )

Is there something incorrect in this code? Because when I do something like this:

data = some_function_that_returns_dict() # Made sure this dict was in the right format
schema = SchemaB()
x = schema.dump(data)

I get dictionary update sequence element #0 has length 1; 2 is required error

@deckar01
Copy link
Member

I'm unable to reproduce that error.

from marshmallow import Schema, fields, post_dump


class SchemaA(Schema):
    field = fields.Dict(
        required=False,
        load_default={},
    )

    def __init__(self, *args, **kwargs):
        self.replace_field_with_string = (
            kwargs.pop('replace_field_with_string', False))
        super().__init__(*args, **kwargs)

    @post_dump
    def convert_field_to_string(self, data, **kwargs):
        if (self.replace_field_with_string and 'field' in data
            and isinstance(data['field'], dict)):
            data['field'] = data['field'].get('string', '')
        return data


class SchemaB(Schema):
    data = fields.List(
        fields.Nested(lambda: SchemaA(replace_field_with_string=True)),
        required=True,
        dump_only=True,
    )

data = {'data': [{'field': {'string': 'bar'}}]}
schema = SchemaB()
x = schema.dump(data)
print(x)
# {'data': [{'field': 'bar'}]}

@qurram-zaheer
Copy link
Author

qurram-zaheer commented Sep 11, 2024

Hm that is interesting. I apologize if I am not explaining this right, but I tried tracing this issue in the debugger and the first thing I noticed was that in schema._serialize (line 521), when it went through the nesting and the attr_name was "field", the field_obj was <fields.Dict>. I thought then it would call Field.serialize and try to serialize a string as a dict, which caused the issue. I'm also seeing in my debugger that self.mapping_type is a dict.

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

2 participants