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

validators called twice #254

Closed
samuelcolvin opened this Issue Aug 29, 2018 · 4 comments

Comments

Projects
None yet
3 participants
@samuelcolvin
Copy link
Owner

samuelcolvin commented Aug 29, 2018

from @dmfigol on gitter:

I am failing to understand why validator is applied several times on the complex field:

import json
from typing import List, Dict, Any

from pydantic import BaseModel, ValidationError, validator

class DemoModel(BaseModel):
    data: Dict[str, Any] = {}

    @validator('data', pre=True, whole=True)
    def json_decode(cls, v):
        print(f'value is {v!r}, type: {type(v)}')
        if isinstance(v, str):
            try:
                return json.loads(v)
            except ValueError:
                pass
        return v

print(DemoModel(data='{"foo": {"bar": 123}}'))

# > value is '{"foo": {"bar": 123}}', type: <class 'str'>
# > value is 'foo', type: <class 'str'>
# > DemoModel data={'foo': {'bar': 123}}

I would appreciate if you could explain :) because of this I spent a lot of time debugging my code and after I found the problem, I still don't understand why it is working this way :(

@samuelcolvin

This comment has been minimized.

Copy link
Owner Author

samuelcolvin commented Aug 29, 2018

Sorry you had trouble. I can understand that this was confusing.

First of all, for parsing json you would be much better off using the Json meta type:

from typing import Dict, Any

from pydantic import BaseModel, Json


class DemoModel(BaseModel):
    data: Json[Dict[str, Any]] = {}

print(DemoModel(data='{"foo": {"bar": 123}}'))

This is documented here unfortunately I broke that section of the docs when last deploying so it wouldn't have made much sense, but it's now fixed

On the particular problem you're having, the reason is that the validator is being called twice is that it's also being called when validating the dict keys:

self.key_field = self._create_sub_type(self.type_.__args__[0], 'key_' + self.name)

I guess this should be fixed so there's another keyword for validators key which means they're called on values, and whole validators shouldn't be called on keys or values.

@samuelcolvin samuelcolvin reopened this Aug 29, 2018

@samuelcolvin samuelcolvin added the bug label Aug 29, 2018

@dmfigol

This comment has been minimized.

Copy link

dmfigol commented Aug 29, 2018

@samuelcolvin thanks for the hint with JSON type and fixing docs!

I guess this should be fixed so there's another keyword for validators key which means they're called on values, and whole validators shouldn't be called on keys or values.

Yeah, I'd expect that the whole validator is applied once and is not invoked later when we are checking the type defined in the annotation.

@samuelcolvin

This comment has been minimized.

Copy link
Owner Author

samuelcolvin commented Oct 10, 2018

@amogorkon this is not related to the issue being discussed here. Would be great if you could create a new issue and delete your comment.

@amogorkon

This comment has been minimized.

Copy link

amogorkon commented Nov 24, 2018

Sorry, didn't notice your reply here. Opened a new issue and deleted comment as requested.

samuelcolvin added a commit that referenced this issue Dec 28, 2018

samuelcolvin added a commit that referenced this issue Dec 28, 2018

dmfigol added a commit to dmfigol/nornir that referenced this issue Jan 20, 2019

Fix build errors
* Add .ipynb_checkpoints to sphinx ignored list
* Run black and pylama on specific folders
* Pin pydantic until 0.19.0 is released
  samuelcolvin/pydantic#254
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment