@@ -2625,8 +2625,26 @@ class Settings(BaseSettings):
26252625 assert s .n .bar == 'bar value'
26262626
26272627
2628+ def no_add_cli_arg_spaces (arg_str : str , has_quote_comma : bool = False ) -> str :
2629+ return arg_str
2630+
2631+
2632+ def add_cli_arg_spaces (arg_str : str , has_quote_comma : bool = False ) -> str :
2633+ arg_str = arg_str .replace ('[' , ' [ ' )
2634+ arg_str = arg_str .replace (']' , ' ] ' )
2635+ arg_str = arg_str .replace ('{' , ' { ' )
2636+ arg_str = arg_str .replace ('}' , ' } ' )
2637+ arg_str = arg_str .replace (':' , ' : ' )
2638+ if not has_quote_comma :
2639+ arg_str = arg_str .replace (',' , ' , ' )
2640+ else :
2641+ arg_str = arg_str .replace ('",' , '" , ' )
2642+ return f' { arg_str } '
2643+
2644+
2645+ @pytest .mark .parametrize ('arg_spaces' , [no_add_cli_arg_spaces , add_cli_arg_spaces ])
26282646@pytest .mark .parametrize ('prefix' , ['' , 'child.' ])
2629- def test_cli_list_arg (prefix ):
2647+ def test_cli_list_arg (prefix , arg_spaces ):
26302648 class Obj (BaseModel ):
26312649 val : int
26322650
@@ -2657,8 +2675,8 @@ def check_answer(cfg, prefix, expected):
26572675 assert cfg .model_dump () == expected
26582676
26592677 args : List [str ] = []
2660- args = [f'--{ prefix } num_list' , '[1,2]' ]
2661- args += [f'--{ prefix } num_list' , '3,4' ]
2678+ args = [f'--{ prefix } num_list' , arg_spaces ( '[1,2]' ) ]
2679+ args += [f'--{ prefix } num_list' , arg_spaces ( '3,4' ) ]
26622680 args += [f'--{ prefix } num_list' , '5' , f'--{ prefix } num_list' , '6' ]
26632681 cfg = Cfg (_cli_parse_args = args )
26642682 expected = {
@@ -2669,9 +2687,9 @@ def check_answer(cfg, prefix, expected):
26692687 }
26702688 check_answer (cfg , prefix , expected )
26712689
2672- args = [f'--{ prefix } obj_list' , '[{"val":1},{"val":2}]' ]
2673- args += [f'--{ prefix } obj_list' , '{"val":3},{"val":4}' ]
2674- args += [f'--{ prefix } obj_list' , '{"val":5}' , f'--{ prefix } obj_list' , '{"val":6}' ]
2690+ args = [f'--{ prefix } obj_list' , arg_spaces ( '[{"val":1},{"val":2}]' ) ]
2691+ args += [f'--{ prefix } obj_list' , arg_spaces ( '{"val":3},{"val":4}' ) ]
2692+ args += [f'--{ prefix } obj_list' , arg_spaces ( '{"val":5}' ) , f'--{ prefix } obj_list' , arg_spaces ( '{"val":6}' ) ]
26752693 cfg = Cfg (_cli_parse_args = args )
26762694 expected = {
26772695 'num_list' : None ,
@@ -2681,9 +2699,9 @@ def check_answer(cfg, prefix, expected):
26812699 }
26822700 check_answer (cfg , prefix , expected )
26832701
2684- args = [f'--{ prefix } union_list' , '[{"val":1},2]' , f'--{ prefix } union_list' , '[3,{"val":4}]' ]
2685- args += [f'--{ prefix } union_list' , '{"val":5},6' , f'--{ prefix } union_list' , '7,{"val":8}' ]
2686- args += [f'--{ prefix } union_list' , '{"val":9}' , f'--{ prefix } union_list' , '10' ]
2702+ args = [f'--{ prefix } union_list' , arg_spaces ( '[{"val":1},2]' ) , f'--{ prefix } union_list' , arg_spaces ( '[3,{"val":4}]' ) ]
2703+ args += [f'--{ prefix } union_list' , arg_spaces ( '{"val":5},6' ) , f'--{ prefix } union_list' , arg_spaces ( '7,{"val":8}' ) ]
2704+ args += [f'--{ prefix } union_list' , arg_spaces ( '{"val":9}' ) , f'--{ prefix } union_list' , '10' ]
26872705 cfg = Cfg (_cli_parse_args = args )
26882706 expected = {
26892707 'num_list' : None ,
@@ -2693,9 +2711,14 @@ def check_answer(cfg, prefix, expected):
26932711 }
26942712 check_answer (cfg , prefix , expected )
26952713
2696- args = [f'--{ prefix } str_list' , '["0,0","1,1"]' ]
2697- args += [f'--{ prefix } str_list' , '"2,2","3,3"' ]
2698- args += [f'--{ prefix } str_list' , '"4,4"' , f'--{ prefix } str_list' , '"5,5"' ]
2714+ args = [f'--{ prefix } str_list' , arg_spaces ('["0,0","1,1"]' , has_quote_comma = True )]
2715+ args += [f'--{ prefix } str_list' , arg_spaces ('"2,2","3,3"' , has_quote_comma = True )]
2716+ args += [
2717+ f'--{ prefix } str_list' ,
2718+ arg_spaces ('"4,4"' , has_quote_comma = True ),
2719+ f'--{ prefix } str_list' ,
2720+ arg_spaces ('"5,5"' , has_quote_comma = True ),
2721+ ]
26992722 cfg = Cfg (_cli_parse_args = args )
27002723 expected = {
27012724 'num_list' : None ,
@@ -2706,29 +2729,31 @@ def check_answer(cfg, prefix, expected):
27062729 check_answer (cfg , prefix , expected )
27072730
27082731
2709- def test_cli_list_json_value_parsing ():
2732+ @pytest .mark .parametrize ('arg_spaces' , [no_add_cli_arg_spaces , add_cli_arg_spaces ])
2733+ def test_cli_list_json_value_parsing (arg_spaces ):
27102734 class Cfg (BaseSettings ):
27112735 json_list : List [Union [str , bool , None ]]
27122736
27132737 assert Cfg (
27142738 _cli_parse_args = [
27152739 '--json_list' ,
2716- 'true,"true"' ,
2740+ arg_spaces ( 'true,"true"' ) ,
27172741 '--json_list' ,
2718- 'false,"false"' ,
2742+ arg_spaces ( 'false,"false"' ) ,
27192743 '--json_list' ,
2720- 'null,"null"' ,
2744+ arg_spaces ( 'null,"null"' ) ,
27212745 '--json_list' ,
2722- 'hi,"bye"' ,
2746+ arg_spaces ( 'hi,"bye"' ) ,
27232747 ]
27242748 ).model_dump () == {'json_list' : [True , 'true' , False , 'false' , None , 'null' , 'hi' , 'bye' ]}
27252749
27262750 assert Cfg (_cli_parse_args = ['--json_list' , '"","","",""' ]).model_dump () == {'json_list' : ['' , '' , '' , '' ]}
27272751 assert Cfg (_cli_parse_args = ['--json_list' , ',,,' ]).model_dump () == {'json_list' : ['' , '' , '' , '' ]}
27282752
27292753
2754+ @pytest .mark .parametrize ('arg_spaces' , [no_add_cli_arg_spaces , add_cli_arg_spaces ])
27302755@pytest .mark .parametrize ('prefix' , ['' , 'child.' ])
2731- def test_cli_dict_arg (prefix ):
2756+ def test_cli_dict_arg (prefix , arg_spaces ):
27322757 class Child (BaseModel ):
27332758 check_dict : Dict [str , str ]
27342759
@@ -2737,19 +2762,34 @@ class Cfg(BaseSettings):
27372762 child : Optional [Child ] = None
27382763
27392764 args : List [str ] = []
2740- args = [f'--{ prefix } check_dict' , '{"k1":"a","k2":"b"}' ]
2741- args += [f'--{ prefix } check_dict' , '{"k3":"c"},{"k4":"d"}' ]
2742- args += [f'--{ prefix } check_dict' , '{"k5":"e"}' , f'--{ prefix } check_dict' , '{"k6":"f"}' ]
2743- args += [f'--{ prefix } check_dict' , '[k7=g,k8=h]' ]
2744- args += [f'--{ prefix } check_dict' , 'k9=i,k10=j' ]
2745- args += [f'--{ prefix } check_dict' , 'k11=k' , f'--{ prefix } check_dict' , 'k12=l' ]
2746- args += [f'--{ prefix } check_dict' , '[{"k13":"m"},k14=n]' , f'--{ prefix } check_dict' , '[k15=o,{"k16":"p"}]' ]
2747- args += [f'--{ prefix } check_dict' , '{"k17":"q"},k18=r' , f'--{ prefix } check_dict' , 'k19=s,{"k20":"t"}' ]
2748- args += [f'--{ prefix } check_dict' , '{"k21":"u"},k22=v,{"k23":"w"}' ]
2749- args += [f'--{ prefix } check_dict' , 'k24=x,{"k25":"y"},k26=z' ]
2750- args += [f'--{ prefix } check_dict' , '[k27="x,y",k28="x,y"]' ]
2751- args += [f'--{ prefix } check_dict' , 'k29="x,y",k30="x,y"' ]
2752- args += [f'--{ prefix } check_dict' , 'k31="x,y"' , f'--{ prefix } check_dict' , 'k32="x,y"' ]
2765+ args = [f'--{ prefix } check_dict' , arg_spaces ('{"k1":"a","k2":"b"}' )]
2766+ args += [f'--{ prefix } check_dict' , arg_spaces ('{"k3":"c"},{"k4":"d"}' )]
2767+ args += [f'--{ prefix } check_dict' , arg_spaces ('{"k5":"e"}' ), f'--{ prefix } check_dict' , arg_spaces ('{"k6":"f"}' )]
2768+ args += [f'--{ prefix } check_dict' , arg_spaces ('[k7=g,k8=h]' )]
2769+ args += [f'--{ prefix } check_dict' , arg_spaces ('k9=i,k10=j' )]
2770+ args += [f'--{ prefix } check_dict' , arg_spaces ('k11=k' ), f'--{ prefix } check_dict' , arg_spaces ('k12=l' )]
2771+ args += [
2772+ f'--{ prefix } check_dict' ,
2773+ arg_spaces ('[{"k13":"m"},k14=n]' ),
2774+ f'--{ prefix } check_dict' ,
2775+ arg_spaces ('[k15=o,{"k16":"p"}]' ),
2776+ ]
2777+ args += [
2778+ f'--{ prefix } check_dict' ,
2779+ arg_spaces ('{"k17":"q"},k18=r' ),
2780+ f'--{ prefix } check_dict' ,
2781+ arg_spaces ('k19=s,{"k20":"t"}' ),
2782+ ]
2783+ args += [f'--{ prefix } check_dict' , arg_spaces ('{"k21":"u"},k22=v,{"k23":"w"}' )]
2784+ args += [f'--{ prefix } check_dict' , arg_spaces ('k24=x,{"k25":"y"},k26=z' )]
2785+ args += [f'--{ prefix } check_dict' , arg_spaces ('[k27="x,y",k28="x,y"]' , has_quote_comma = True )]
2786+ args += [f'--{ prefix } check_dict' , arg_spaces ('k29="x,y",k30="x,y"' , has_quote_comma = True )]
2787+ args += [
2788+ f'--{ prefix } check_dict' ,
2789+ arg_spaces ('k31="x,y"' , has_quote_comma = True ),
2790+ f'--{ prefix } check_dict' ,
2791+ arg_spaces ('k32="x,y"' , has_quote_comma = True ),
2792+ ]
27532793 cfg = Cfg (_cli_parse_args = args )
27542794 expected : Dict [str , Any ] = {
27552795 'check_dict' : {
0 commit comments