Skip to content

Commit 8670e99

Browse files
committed
Use Pydantic model_dump in serializer
1 parent 0e96e9c commit 8670e99

1 file changed

Lines changed: 13 additions & 6 deletions

File tree

  • pydantic_settings/sources/providers

pydantic_settings/sources/providers/cli.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
)
3838

3939
import typing_extensions
40-
from pydantic import AliasChoices, AliasPath, BaseModel, Field, PrivateAttr
40+
from pydantic import AliasChoices, AliasPath, BaseModel, Field, PrivateAttr, TypeAdapter
4141
from pydantic._internal._repr import Representation
4242
from pydantic._internal._utils import is_model_class
4343
from pydantic.dataclasses import is_pydantic_dataclass
@@ -1399,6 +1399,12 @@ def _serialized_args(
13991399
optional_args: list[str | list[Any] | dict[str, Any]] = []
14001400
positional_args: list[str | list[Any] | dict[str, Any]] = []
14011401
subcommand_args: list[str] = []
1402+
if is_model_class(type(model)) and hasattr(model, 'model_dump'):
1403+
dumped_model = model.model_dump(mode='json')
1404+
elif is_pydantic_dataclass(type(model)):
1405+
dumped_model = TypeAdapter(type(model)).dump_python(model, mode='json')
1406+
else:
1407+
raise ValueError(f'unsupported type: {type(model)}')
14021408
for field_name, field_info in _get_model_fields(type(model) if _is_submodel else self.settings_cls).items():
14031409
model_default = getattr(model, field_name)
14041410
if field_info.default == model_default:
@@ -1432,8 +1438,9 @@ def _serialized_args(
14321438

14331439
matched = re.match(r'(-*)(.+)', arg.preferred_arg_name)
14341440
flag_chars, arg_name = matched.groups() if matched else ('', '')
1441+
dumped_field = dumped_model[field_name]
14351442
value: str | list[Any] | dict[str, Any] = (
1436-
json.dumps(model_default) if isinstance(model_default, (dict, list, set)) else str(model_default)
1443+
json.dumps(dumped_field) if isinstance(dumped_field, (dict, list, set)) else str(dumped_field)
14371444
)
14381445

14391446
if arg.is_alias_path_only:
@@ -1443,16 +1450,16 @@ def _serialized_args(
14431450
value = self._update_alias_path_only_default(arg_name, value, field_info, alias_path_only_defaults)
14441451

14451452
if _CliPositionalArg in field_info.metadata:
1446-
for value in model_default if isinstance(model_default, list) else [model_default]:
1453+
for value in dumped_field if isinstance(dumped_field, list) else [dumped_field]:
14471454
value = json.dumps(value) if isinstance(value, (dict, list, set)) else str(value)
14481455
positional_args.append(value)
14491456
continue
14501457

1451-
# Note: prepend 'no-' for boolean optional action flag if model_default value is False and flag is not a short option
1452-
if arg.kwargs.get('action') == BooleanOptionalAction and model_default is False and flag_chars == '--':
1458+
# Note: prepend 'no-' for boolean optional action flag if dumped_field value is False and flag is not a short option
1459+
if arg.kwargs.get('action') == BooleanOptionalAction and dumped_field is False and flag_chars == '--':
14531460
flag_chars += 'no-'
14541461

1455-
for value in self._coerce_value_styles(model_default, value, list_style=list_style, dict_style=dict_style):
1462+
for value in self._coerce_value_styles(dumped_field, value, list_style=list_style, dict_style=dict_style):
14561463
optional_args.append(f'{flag_chars}{arg_name}')
14571464

14581465
# If implicit bool flag, do not add a value

0 commit comments

Comments
 (0)