@@ -51,7 +51,7 @@ class SettingsError(ValueError): ...
5151
5252
5353class BaseSettingsSource (abc .ABC ):
54- def __init__ (self , settings_cls : type ["BaseSettings" ]) -> None :
54+ def __init__ (self , settings_cls : type [BaseModel ]) -> None :
5555 self .settings_cls = settings_cls
5656
5757 @property
@@ -67,7 +67,7 @@ class InitSettingsSource(BaseSettingsSource):
6767 __slots__ = ("init_kwargs" ,)
6868
6969 def __init__ (
70- self , settings_cls : type ["BaseSettings" ], init_kwargs : dict [str , Any ]
70+ self , settings_cls : type [BaseModel ], init_kwargs : dict [str , Any ]
7171 ) -> None :
7272 self .init_kwargs = init_kwargs
7373 super ().__init__ (settings_cls )
@@ -82,33 +82,17 @@ def __repr__(self) -> str:
8282class DotEnvSettingsSource (BaseSettingsSource ):
8383 def __init__ (
8484 self ,
85- settings_cls : type ["BaseSettings" ],
86- env_file : Optional [DOTENV_TYPE ] = ENV_FILE_SENTINEL ,
87- env_file_encoding : Optional [ str ] = None ,
88- case_sensitive : Optional [bool ] = None ,
85+ settings_cls : type [BaseModel ],
86+ env_file : Optional [DOTENV_TYPE ],
87+ env_file_encoding : str ,
88+ case_sensitive : Optional [bool ] = False ,
8989 env_nested_delimiter : Optional [str ] = None ,
9090 ) -> None :
9191 super ().__init__ (settings_cls )
92- self .env_file = (
93- env_file
94- if env_file is not ENV_FILE_SENTINEL
95- else self .config .get ("env_file" , (".env" ,))
96- )
97- self .env_file_encoding = (
98- env_file_encoding
99- if env_file_encoding is not None
100- else self .config .get ("env_file_encoding" , "utf-8" )
101- )
102- self .case_sensitive = (
103- case_sensitive
104- if case_sensitive is not None
105- else self .config .get ("case_sensitive" , False )
106- )
107- self .env_nested_delimiter = (
108- env_nested_delimiter
109- if env_nested_delimiter is not None
110- else self .config .get ("env_nested_delimiter" , None )
111- )
92+ self .env_file = env_file
93+ self .env_file_encoding = env_file_encoding
94+ self .case_sensitive = case_sensitive
95+ self .env_nested_delimiter = env_nested_delimiter
11296
11397 def _apply_case_sensitive (self , var_name : str ) -> str :
11498 return var_name if self .case_sensitive else var_name .lower ()
@@ -212,12 +196,33 @@ def __call__(self) -> dict[str, Any]:
212196 for field in model_fields (self .settings_cls ):
213197 field_name = field .name
214198 env_name = self ._apply_case_sensitive (field_name )
199+ alias_name = field .field_info .alias
200+ alias_env_name = (
201+ None if alias_name is None else self ._apply_case_sensitive (alias_name )
202+ )
203+
204+ # pydantic use alias name to validate if exist
205+ if alias_name is not None :
206+ field_name = alias_name
215207
216208 # try get values from env vars
217209 env_val = env_vars .get (env_name , PydanticUndefined )
210+ alias_env_val = (
211+ PydanticUndefined
212+ if alias_env_name is None
213+ else env_vars .get (alias_env_name , PydanticUndefined )
214+ )
215+ # alias env value has higher priority
216+ env_val = (
217+ env_val
218+ if isinstance (alias_env_val , PydanticUndefinedType )
219+ else alias_env_val
220+ )
218221 # delete from file vars when used
219222 if env_name in env_file_vars :
220223 del env_file_vars [env_name ]
224+ if alias_env_name is not None and alias_env_name in env_file_vars :
225+ del env_file_vars [alias_env_name ]
221226
222227 is_complex , allow_parse_failure = self ._field_is_complex (field )
223228 if is_complex :
@@ -331,25 +336,48 @@ def __init__(
331336 _env_nested_delimiter : Optional [str ] = None ,
332337 ** values : Any ,
333338 ) -> None :
339+ settings_config = model_config (__settings_self__ .__class__ )
340+ env_file = (
341+ _env_file
342+ if _env_file is not ENV_FILE_SENTINEL
343+ else settings_config .get ("env_file" , (".env" ,))
344+ )
345+ env_file_encoding = (
346+ _env_file_encoding
347+ if _env_file_encoding is not None
348+ else settings_config .get ("env_file_encoding" , "utf-8" )
349+ )
350+ env_nested_delimiter = (
351+ _env_nested_delimiter
352+ if _env_nested_delimiter is not None
353+ else settings_config .get ("env_nested_delimiter" , None )
354+ )
355+
334356 super ().__init__ (
335357 ** __settings_self__ ._settings_build_values (
358+ __settings_self__ .__class__ ,
336359 values ,
337- env_file = _env_file ,
338- env_file_encoding = _env_file_encoding ,
339- env_nested_delimiter = _env_nested_delimiter ,
360+ env_file = env_file ,
361+ env_file_encoding = env_file_encoding ,
362+ env_nested_delimiter = env_nested_delimiter ,
340363 )
341364 )
342365
366+ __settings_self__ ._env_file = env_file
367+ __settings_self__ ._env_file_encoding = env_file_encoding
368+ __settings_self__ ._env_nested_delimiter = env_nested_delimiter
369+
370+ @staticmethod
343371 def _settings_build_values (
344- self ,
372+ settings_cls : type [ BaseModel ] ,
345373 init_kwargs : dict [str , Any ],
346- env_file : Optional [DOTENV_TYPE ] = None ,
347- env_file_encoding : Optional [ str ] = None ,
348- env_nested_delimiter : Optional [str ] = None ,
374+ env_file : Optional [DOTENV_TYPE ],
375+ env_file_encoding : str ,
376+ env_nested_delimiter : Optional [str ],
349377 ) -> dict [str , Any ]:
350- init_settings = InitSettingsSource (self . __class__ , init_kwargs = init_kwargs )
378+ init_settings = InitSettingsSource (settings_cls , init_kwargs = init_kwargs )
351379 env_settings = DotEnvSettingsSource (
352- self . __class__ ,
380+ settings_cls ,
353381 env_file = env_file ,
354382 env_file_encoding = env_file_encoding ,
355383 env_nested_delimiter = env_nested_delimiter ,
0 commit comments