Skip to content

Commit

Permalink
Move preferred alias resolution to private method (#507)
Browse files Browse the repository at this point in the history
  • Loading branch information
kschwab authored Dec 31, 2024
1 parent 95fae54 commit 66ecc3a
Showing 1 changed file with 32 additions and 17 deletions.
49 changes: 32 additions & 17 deletions pydantic_settings/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str,
field_name: The field name.
Returns:
A tuple contains the key, value and a flag to determine whether value is complex.
A tuple that contains the value, key and a flag to determine whether value is complex.
"""
pass

Expand Down Expand Up @@ -562,12 +562,35 @@ def _replace_env_none_type_values(self, field_value: dict[str, Any]) -> dict[str

return values

def _get_resolved_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str, bool]:
"""
Gets the value, the preferred alias key for model creation, and a flag to determine whether value
is complex.
Note:
In V3, this method should either be made public, or, this method should be removed and the
abstract method get_field_value should be updated to include a "use_preferred_alias" flag.
Args:
field: The field.
field_name: The field name.
Returns:
A tuple that contains the value, preferred key and a flag to determine whether value is complex.
"""
field_value, field_key, value_is_complex = self.get_field_value(field, field_name)
if not (value_is_complex or (self.config.get('populate_by_name', False) and (field_key == field_name))):
field_infos = self._extract_field_info(field, field_name)
preferred_key, *_ = field_infos[0]
return field_value, preferred_key, value_is_complex
return field_value, field_key, value_is_complex

def __call__(self) -> dict[str, Any]:
data: dict[str, Any] = {}

for field_name, field in self.settings_cls.model_fields.items():
try:
field_value, field_key, value_is_complex = self.get_field_value(field, field_name)
field_value, field_key, value_is_complex = self._get_resolved_field_value(field, field_name)
except Exception as e:
raise SettingsError(
f'error getting value for field "{field_name}" from source "{self.__class__.__name__}"'
Expand Down Expand Up @@ -675,13 +698,11 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str,
field_name: The field name.
Returns:
A tuple contains the key, value if the file exists otherwise `None`, and
A tuple that contains the value (`None` if the file does not exist), key, and
a flag to determine whether value is complex.
"""

field_infos = self._extract_field_info(field, field_name)
preferred_key, *_ = field_infos[0]
for field_key, env_name, value_is_complex in field_infos:
for field_key, env_name, value_is_complex in self._extract_field_info(field, field_name):
# paths reversed to match the last-wins behaviour of `env_file`
for secrets_path in reversed(self.secrets_paths):
path = self.find_case_path(secrets_path, env_name, self.case_sensitive)
Expand All @@ -690,16 +711,14 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str,
continue

if path.is_file():
if value_is_complex or (self.config.get('populate_by_name', False) and (field_key == field_name)):
preferred_key = field_key
return path.read_text().strip(), preferred_key, value_is_complex
return path.read_text().strip(), field_key, value_is_complex
else:
warnings.warn(
f'attempted to load secret file "{path}" but found a {path_type_label(path)} instead.',
stacklevel=4,
)

return None, preferred_key, value_is_complex
return None, field_key, value_is_complex

def __repr__(self) -> str:
return f'{self.__class__.__name__}(secrets_dir={self.secrets_dir!r})'
Expand Down Expand Up @@ -742,21 +761,17 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str,
field_name: The field name.
Returns:
A tuple contains the key, value if the file exists otherwise `None`, and
A tuple that contains the value (`None` if not found), key, and
a flag to determine whether value is complex.
"""

env_val: str | None = None
field_infos = self._extract_field_info(field, field_name)
preferred_key, *_ = field_infos[0]
for field_key, env_name, value_is_complex in field_infos:
for field_key, env_name, value_is_complex in self._extract_field_info(field, field_name):
env_val = self.env_vars.get(env_name)
if env_val is not None:
if value_is_complex or (self.config.get('populate_by_name', False) and (field_key == field_name)):
preferred_key = field_key
break

return env_val, preferred_key, value_is_complex
return env_val, field_key, value_is_complex

def prepare_field_value(self, field_name: str, field: FieldInfo, value: Any, value_is_complex: bool) -> Any:
"""
Expand Down

0 comments on commit 66ecc3a

Please sign in to comment.