@@ -2531,6 +2531,33 @@ class Options(BaseSettings):
2531
2531
assert CliApp .run (Options , cli_args = ['--nested.foo=5' ]).model_dump () == {'nested' : {'foo' : 5 , 'bar' : 2 }}
2532
2532
2533
2533
2534
+ def test_cli_parse_args_from_model_config_is_respected_with_settings_customise_sources (
2535
+ monkeypatch : pytest .MonkeyPatch ,
2536
+ ):
2537
+ class MySettings (BaseSettings ):
2538
+ model_config = SettingsConfigDict (cli_parse_args = True )
2539
+
2540
+ foo : str
2541
+
2542
+ @classmethod
2543
+ def settings_customise_sources (
2544
+ cls ,
2545
+ settings_cls : type [BaseSettings ],
2546
+ init_settings : PydanticBaseSettingsSource ,
2547
+ env_settings : PydanticBaseSettingsSource ,
2548
+ dotenv_settings : PydanticBaseSettingsSource ,
2549
+ file_secret_settings : PydanticBaseSettingsSource ,
2550
+ ) -> tuple [PydanticBaseSettingsSource , ...]:
2551
+ return (CliSettingsSource (settings_cls ),)
2552
+
2553
+ with monkeypatch .context () as m :
2554
+ m .setattr (sys , 'argv' , ['example.py' , '--foo' , 'bar' ])
2555
+
2556
+ cfg = CliApp .run (MySettings )
2557
+
2558
+ assert cfg .model_dump () == {'foo' : 'bar' }
2559
+
2560
+
2534
2561
def test_cli_shortcuts_on_flat_object ():
2535
2562
class Settings (BaseSettings ):
2536
2563
option : str = Field (default = 'foo' )
@@ -2612,3 +2639,25 @@ class Cfg(BaseSettings):
2612
2639
serialized_cli_args = CliApp .serialize (cfg )
2613
2640
assert serialized_cli_args == ['0' , '1' , '2' , '3' , '4' , '5' ]
2614
2641
assert CliApp .run (Cfg , cli_args = serialized_cli_args ).model_dump () == cfg .model_dump ()
2642
+
2643
+
2644
+ def test_cli_app_with_separate_parser (monkeypatch ):
2645
+ class Cfg (BaseSettings ):
2646
+ model_config = SettingsConfigDict (cli_parse_args = True )
2647
+ pet : Literal ['dog' , 'cat' , 'bird' ]
2648
+
2649
+ parser = argparse .ArgumentParser ()
2650
+
2651
+ # The actual parsing of command line argument should not happen here.
2652
+ cli_settings = CliSettingsSource (Cfg , root_parser = parser )
2653
+
2654
+ parser .add_argument ('-e' , '--extra' , dest = 'extra' , default = 0 , action = 'count' )
2655
+
2656
+ with monkeypatch .context () as m :
2657
+ m .setattr (sys , 'argv' , ['example.py' , '--pet' , 'dog' , '-eeee' ])
2658
+
2659
+ parsed_args = parser .parse_args ()
2660
+
2661
+ assert parsed_args .extra == 4
2662
+ # With parsed arguments passed to CliApp.run, the parser should not need to be called again.
2663
+ assert CliApp .run (Cfg , cli_args = parsed_args , cli_settings_source = cli_settings ).model_dump () == {'pet' : 'dog' }
0 commit comments