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

Parser.parse adds "missing" to original_data #146

Closed
lafrech opened this issue Nov 29, 2016 · 2 comments

Comments

@lafrech
Copy link
Member

commented Nov 29, 2016

When parsing input, parser.parse adds 'field': missing to original_data for every missing field. This happens only at first level, not in nested schema.

Hopefully, this test case will make this clearer:

from marshmallow import Schema, fields, validates_schema

from webargs.flaskparser import parser

class Location(Schema):

    city = fields.Str()
    country = fields.Str()

class User(Schema):

    name = fields.Str()
    location = fields.Nested(Location)

    @validates_schema(pass_original=True)
    def print_original_data(self, data, original_data):
        print(original_data)

    class Meta:
        strict = True

input_1 = {'name': 'Eric Cartman'}
input_2 = {'location': {'city': 'South Park'}}

# Via pure Marshmallow
User().load(input_1)
User().load(input_2)
# {'name': 'Eric Cartman'}
# {'location': {'city': 'South Park'}}

# Mock Flask request object
class Request():
    def __init__(self, args):
        self.args = args

req_1 = Request(input_1)
req_2 = Request(input_2)

# Via webargs
parser.parse(User, req_1, locations=['query'])
parser.parse(User, req_2, locations=['query'])
# {'location': <marshmallow.missing>, 'name': 'Eric Cartman'}
# {'location': {'city': 'South Park'}, 'name': <marshmallow.missing>}

AFAIKT, this should not happen. I'd expect original_data to be the same as when using pure Marshmallow.

I could fix this by modifying _parse_requestlike this:

            argdict = schema.fields
            parsed = {}
            for argname, field_obj in iteritems(argdict):
                parsed_value = self.parse_arg(argname, field_obj, req, locations)
                # If load_from is specified on the field, try to parse from that key
                if parsed_value is missing and field_obj.load_from:
                    parsed_value = self.parse_arg(field_obj.load_from, field_obj, req, locations)
                    argname = field_obj.load_from
                # Only add value if not missing
                if parsed_value is not missing:
                    parsed[argname] = parsed_value

Is this the correct thing to do?

lafrech added a commit to Nobatek/webargs that referenced this issue Nov 29, 2016

@lafrech

This comment has been minimized.

Copy link
Member Author

commented Nov 29, 2016

@sloria

This comment has been minimized.

Copy link
Member

commented Jan 8, 2017

@lafrech Thank you for reporting this. This is a legitimate bug and I was able to reproduce it (thanks for the example).

I've created a PR with your fix in #147

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.