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

[feature] Optionally Include settings source in ValidationError #544

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

AlbertDeFusco
Copy link

When working with settings configured for multiple sources it can be hard to pin down the exact source of a validation error. See #538

In this PR I've added a configuration parameter validate_each_source=True that performs the validation while constructing the merged state of all configured sources. All validation errors are collected and raised after all sources have been parsed. The settings source is prepended to the loc field. Further, type=missing line errors are checked using the fully merged state and added to the raised ValidationError exception.

Here is an example using the Init and Env sources.

import os
from pydantic_settings import BaseSettings

class MySettings(BaseSettings, validate_each_source=True, env_prefix='settings_'):
    foo: str
    default: int = 0
    extra: str | None = None

os.environ['settings_default'] = 'a'
settings = MySettings(extra=0)

The following error message is reported

Traceback (most recent call last):
  File "/Users/adefusco/Development/pydantic/pydantic-settings/testy.py", line 10, in <module>
    settings = MySettings(extra=0)
               ^^^^^^^^^^^^^^^^^^^
  File "/Users/adefusco/Development/pydantic/pydantic-settings/pydantic_settings/main.py", line 182, in __init__
    **self._settings_build_values(
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/adefusco/Development/pydantic/pydantic-settings/pydantic_settings/main.py", line 451, in _settings_build_values
    raise ValidationError.from_exception_data(
pydantic_core._pydantic_core.ValidationError: 3 validation errors for MySettings
InitSettingsSource.extra
  Input should be a valid string [type=string_type, input_value=0, input_type=int]
    For further information visit https://errors.pydantic.dev/2.10/v/string_type
EnvSettingsSource.default
  Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='a', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/int_parsing
foo
  Field required [type=missing, input_value={'default': 'a', 'extra': 0}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing

@hramezani
Copy link
Member

Thanks @AlbertDeFusco for this PR.

‌In this PR I've added a configuration parameter validate_each_source=True that performs the validation while constructing the merged state of all configured sources.

I think we decided to have a flag to print out collected values for each source.

@AlbertDeFusco
Copy link
Author

I can add that. Maybe an env var like PYDANTIC_SETTINGS_DEBUG_SOURCE_INPUTS=1 to log the parsed source states?

@hramezani
Copy link
Member

I can add that. Maybe an env var like PYDANTIC_SETTINGS_DEBUG_SOURCE_INPUTS=1 to log the parsed source states?

Looks good. please make another PR for it.

BTW, I am not sure we want to add the validate_each_source configuration. I can't see any value in validating every source data separately.

@AlbertDeFusco
Copy link
Author

I can agree that validating each source is excessive. I'll work on some alternate implementations to provide source information in the ValidationError

@hramezani
Copy link
Member

I can agree that validating each source is excessive. I'll work on some alternate implementations to provide source information in the ValidationError

JFYI, At the point of validation, we don't know which data comes from which sources because pydantic-settings merges values from all the sources.

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

Successfully merging this pull request may close these issues.

2 participants