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

context not passed to field validators #407

Closed
1 task done
aidanmontare-fed opened this issue Sep 16, 2024 · 5 comments · Fixed by #417
Closed
1 task done

context not passed to field validators #407

aidanmontare-fed opened this issue Sep 16, 2024 · 5 comments · Fixed by #417
Labels
bug Something isn't working

Comments

@aidanmontare-fed
Copy link

moving here from #pydantic/pydantic#10418

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Hi there! It appears that the context arg that can be passed to model_validate does not work when using Pydantic Settings, when it does work using a regular Pydantic model.

Example Code

Python 3.12.6 (main, Sep 13 2024, 19:07:08) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.27.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from pydantic_settings import *

In [2]: from pydantic import *

In [3]: class Settings(BaseSettings):
   ...:     text: str
   ...:     @field_validator('text')
   ...:     @classmethod
   ...:     def test_validator(cls, v: str, info: ValidationInfo):
   ...:         context = info.context
   ...:         print(f'{context=}')
   ...:         if context:
   ...:             print('have context')
   ...:         return v
   ...:

In [4]: Settings.model_validate({'text': 'foo bar'})
context=None
Out[4]: Settings(text='foo bar')

In [5]: Settings.model_validate({'text': 'foo bar'}, context={'biz': 'baz'}) # can't see context
context=None
Out[5]: Settings(text='foo bar')

In [6]: class Model(BaseModel):
   ...:     text: str
   ...:     @field_validator('text')
   ...:     @classmethod
   ...:     def test_validator(cls, v: str, info: ValidationInfo):
   ...:         context = info.context
   ...:         print(f'{context=}')
   ...:         if context:
   ...:             print('have context')
   ...:         return v
   ...:

In [7]: Model.model_validate({'text': 'foo bar'})
context=None
Out[7]: Model(text='foo bar')

In [8]: Model.model_validate({'text': 'foo bar'}, context={'biz': 'baz'}) # but this one does
context={'biz': 'baz'}
have context
Out[8]: Model(text='foo bar')

In [9]:

Python, Pydantic & OS Version

pydantic version: 2.9.1
        pydantic-core version: 2.23.3
          pydantic-core build: profile=release pgo=false
                 install path: /home/aam7/.pyenv/versions/3.12.6/envs/bug/lib/python3.12/site-packages/pydantic
               python version: 3.12.6 (main, Sep 13 2024, 19:07:08) [GCC 11.4.0]
                     platform: Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.35
             related packages: typing_extensions-4.12.2 pydantic-settings-2.5.2
                       commit: unknown
@hramezani
Copy link
Member

Thanks @aidanmontare-fed for reporting this bug. I will prepare a fix.

@hramezani
Copy link
Member

@aidanmontare-fed I created #417 to fix the problem.

Could you please confirm?

@aidanmontare-fed
Copy link
Author

@hramezani just checked it out and it works great! Thanks so much!

@hramezani
Copy link
Member

Thanks @aidanmontare-fed for reporting the bug and confirming the fix.

The fix will be available in the next release!

@hramezani
Copy link
Member

@aidanmontare-fed I have to revert the fix.
Actually, the issue is related to pydantic pydantic/pydantic#10062

The fix that I did caused a lot of issues for current users and had to be reverted. Here are some of the issues:

You can solve your problem by adding __init__.__pydantic_base_init__ = True to your model before the real fix in pydantic. but you have to take care about the other issues that might happen:

class Settings(BaseSettings):
    text: str

    def __init__(self, **data):
        super().__init__(**data)

    __init__.__pydantic_base_init__ = True

    @field_validator('text')
    @classmethod
    def test_validator(cls, v: str, info: ValidationInfo):
        context = info.context
        print(f'{context=}')
        if context:
            print('have context')
        return v


Settings.model_validate({'text': 'foo bar'}, context={'biz': 'baz'})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants