question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Non-iterable values get passed as [] to @pre_load @validates_schema et al.

See original GitHub issue

With:

class Foo(StrictSchema):
    foo = fields.Str()

parser = FlaskParser()
    
req = Mock()
req.mimetype = 'application/json'
req.get_json = lambda *_, **__: {'foo': 1}  # or any non-iterable

parser.parse(Foo(strict=True, many=True), req=req, locations=('json', ))

@pre_load(pass_original=True) @validate_schema(pass_original=True) get [] as original value, instead of {'foo': 1}.

This makes it impossible to record errors about invalid base type / extra fields.

This happens for any non-iterable non-string non-mapping value.

The code that’s related to this is in get_value() at https://github.com/sloria/webargs/blob/dev/webargs/core.py#L130-L132. Not yet sure what all that processing really does, but could that function return the data as is…?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
lafrechcommented, Jan 31, 2020

Thanks for looking into this.

1reaction
tuukkamustonencommented, Jan 31, 2020

The problem was with many=True. Added that and made @pre_load take pass_many=True:

import marshmallow as ma
from marshmallow import Schema, fields
from webargs.flaskparser import FlaskParser
from unittest.mock import Mock


class Foo(Schema):

    # Both raise
    @ma.pre_load(pass_many=True)
    def test_pre_load(self, data, **kwargs):
        print('@pre_load data:', data)
        return data

    @ma.validates_schema(pass_original=True)
    def test_validates_schema(self, data, original_data, **kwargs):
        print('@validates_schema data:', data)
        print('@validates_schema original_data:', original_data)
        return data

    foo = fields.Str()


parser = FlaskParser()

req = Mock()
req.mimetype = 'application/json'
req.get_data = lambda *_, **__: '{"foo": "1"}'  # or any non-iterable

parser.parse(Foo(many=True), req=req, location='json')

Prints:

@pre_load data: {'foo': '1'}
Traceback (most recent call last):
    ...
packages/marshmallow/schema.py", line 892, in _do_load
    raise exc
marshmallow.exceptions.ValidationError: {'_schema': ['Invalid input type.']}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
    ...
werkzeug.exceptions.UnprocessableEntity: 422 Unprocessable Entity: The request was well-formed but was unable to be followed due to semantic errors.

So @pre_load works as expected, it now gets the original payload passed in, as should. This didn’t work earlier so it’s now fixed.

@validates_schema never evaluates now, because exception is raised before it. I don’t know if this is how it should work by design, but I guess yes. IIRC, the problem with earlier versions was that they failed to ensure that given payload was actually an array, when many=True was passed in. Now it seems to do that, and error gets risen. I think current logic is good.

So yeah, let’s assume this fixed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JSON Schema validation - both values should not be false at ...
To validate this, we need two schemas: one to validate value1 is true and value2 is true . Then we put both of...
Read more >
Extending Schemas — marshmallow 3.19.0 documentation
The method receives the ValidationError and the original input data to be deserialized.
Read more >
jquense/yup: Dead simple Object schema validation - GitHub
Yup is a schema builder for runtime value parsing and validation. ... Watch out! values are not guaranteed to be valid types in...
Read more >
Validation Rules — Cerberus is a lightweight and extensible ...
This rule takes a collectionsabc.Container of allowed values. Validates the target value if the value is in the allowed values. If the target...
Read more >
Validating Data With JSON-Schema, Part 2 - Code
JSON-pointers can be used not only in JSON-schemas. ... One approach is to have all connected schemas preloaded like we had in the ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found