-
-
Notifications
You must be signed in to change notification settings - Fork 105
Description
When a setting class uses multiple aliases for one of the fields, a validation error is raised if I use one alias in the constructor,
but there is an environment variable with the name of the other alias.
This is the version of the packages I have installed:
pydantic==2.6.4
pydantic-settings==2.2.1
pydantic_core==2.16.3
I define a class like:
from pydantic import Field, AliasChoices
from pydantic_settings import BaseSettings, SettingsConfigDict
class Example(BaseSettings):
model_config = SettingsConfigDict(env_prefix='PREFIX')
name: str
last_name: str = Field(validation_alias=AliasChoices("PREFIX_LAST_NAME", "PREFIX_SURNAME"))
If I run:
Example(name="john", PREFIX_LAST_NAME="doe")
the object is validated correctly.
However, if there was an environment PREFIX_SURNAME, then the validation would fail.
For example:
import os
os.environ["PREFIX_SURNAME"] = "smith"
Example(name="john", PREFIX_LAST_NAME="doe")
fails with this error:
ValidationError Traceback (most recent call last)
Cell In[26], line 1
----> 1 Example(name="john", PREFIX_LAST_NAME="doe")
File ~/miniforge3/envs/domestika-redshift-dev/lib/python3.12/site-packages/pydantic_settings/main.py:84, in BaseSettings.__init__(__pydantic_self__, _case_sensitive, _env_prefix, _env_file, _env_file_encoding, _env_ignore_empty, _env_nested_delimiter, _env_parse_none_str, _secrets_dir, **values)
71 def __init__(
72 __pydantic_self__,
73 _case_sensitive: bool | None = None,
(...)
82 ) -> None:
83 # Uses something other than `self` the first arg to allow "self" as a settable attribute
---> 84 super().__init__(
85 **__pydantic_self__._settings_build_values(
86 values,
87 _case_sensitive=_case_sensitive,
88 _env_prefix=_env_prefix,
89 _env_file=_env_file,
90 _env_file_encoding=_env_file_encoding,
91 _env_ignore_empty=_env_ignore_empty,
92 _env_nested_delimiter=_env_nested_delimiter,
93 _env_parse_none_str=_env_parse_none_str,
94 _secrets_dir=_secrets_dir,
95 )
96 )
File ~/miniforge3/envs/domestika-redshift-dev/lib/python3.12/site-packages/pydantic/main.py:171, in BaseModel.__init__(self, **data)
169 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
170 __tracebackhide__ = True
--> 171 self.__pydantic_validator__.validate_python(data, self_instance=self)
ValidationError: 1 validation error for Example
PREFIX_SURNAME
Extra inputs are not permitted [type=extra_forbidden, input_value='smith', input_type=str]
For further information visit https://errors.pydantic.dev/2.6/v/extra_forbidden
however:
import os
os.environ["PREFIX_SURNAME"] = "smith"
Example(name="john", PREFIX_SURNAME="doe")
works as I expected, and uses the value "doe" that I explicitly passed through the constructor.
Maybe I have the wrong expectation, but I thought that if I explicitly constructed the object using one of the two aliases, the value coming from the environment should have been discarded, and not passed as an extra argument to the object causing the validation error.