@@ -499,14 +499,14 @@ class Car(BaseSettings, cli_parse_args=True):
499499 Car ()
500500 assert (
501501 capsys .readouterr ().out
502- == f"""usage: example.py [-h] [--driver JSON] [--driver.meow str ] [--driver.bark str]
503- [--driver.caww str] [--driver.tweet str]
502+ == f"""usage: example.py [-h] [--driver [ JSON]] [--driver.meow str]
503+ [--driver.bark str] [--driver. caww str] [--driver.tweet str]
504504
505505{ ARGPARSE_OPTIONS_TEXT } :
506506 -h, --help show this help message and exit
507507
508508driver options:
509- --driver JSON set driver from JSON string
509+ --driver [ JSON] set driver from JSON string (default: {{}})
510510 --driver.meow str (default: purr)
511511 --driver.bark str (default: bark)
512512 --driver.caww str (default: caww)
@@ -540,73 +540,75 @@ class Settings(BaseSettings, cli_parse_args=True):
540540 Settings ()
541541 assert (
542542 capsys .readouterr ().out
543- == f"""usage: example.py [-h] [--flag bool] [--sub_model JSON]
544- [--sub_model.flag bool] [--sub_model.deep JSON]
543+ == f"""usage: example.py [-h] [--flag bool] [--sub_model [ JSON] ]
544+ [--sub_model.flag bool] [--sub_model.deep [ JSON] ]
545545 [--sub_model.deep.flag bool]
546- [--sub_model.deep.deeper {{JSON,null}}]
546+ [--sub_model.deep.deeper [ {{JSON,null}}] ]
547547 [--sub_model.deep.deeper.flag bool]
548- [--opt_model {{JSON,null}}] [--opt_model.flag bool]
549- [--opt_model.deeper {{JSON,null}}]
550- [--opt_model.deeper.flag bool] [--fact_model JSON]
551- [--fact_model.flag bool] [--fact_model.deep JSON]
548+ [--opt_model [ {{JSON,null}}] ] [--opt_model.flag bool]
549+ [--opt_model.deeper [ {{JSON,null}}] ]
550+ [--opt_model.deeper.flag bool] [--fact_model [ JSON] ]
551+ [--fact_model.flag bool] [--fact_model.deep [ JSON] ]
552552 [--fact_model.deep.flag bool]
553- [--fact_model.deep.deeper {{JSON,null}}]
553+ [--fact_model.deep.deeper [ {{JSON,null}}] ]
554554 [--fact_model.deep.deeper.flag bool]
555555
556556{ ARGPARSE_OPTIONS_TEXT } :
557557 -h, --help show this help message and exit
558558 --flag bool (default: True)
559559
560560sub_model options:
561- --sub_model JSON set sub_model from JSON string
561+ --sub_model [ JSON] set sub_model from JSON string (default: {{}})
562562 --sub_model.flag bool
563563 (default: False)
564564
565565sub_model.deep options:
566- --sub_model.deep JSON
567- set sub_model.deep from JSON string
566+ --sub_model.deep [ JSON]
567+ set sub_model.deep from JSON string (default: {{}})
568568 --sub_model.deep.flag bool
569569 (default: True)
570570
571571sub_model.deep.deeper options:
572572 default: null (undefined)
573573
574- --sub_model.deep.deeper {{JSON,null}}
575- set sub_model.deep.deeper from JSON string
574+ --sub_model.deep.deeper [{{JSON,null}}]
575+ set sub_model.deep.deeper from JSON string (default:
576+ {{}})
576577 --sub_model.deep.deeper.flag bool
577578 (ifdef: required)
578579
579580opt_model options:
580581 default: null (undefined)
581582 Group Doc
582583
583- --opt_model {{JSON,null}}
584- set opt_model from JSON string
584+ --opt_model [ {{JSON,null}}]
585+ set opt_model from JSON string (default: {{}})
585586 --opt_model.flag bool
586587 (ifdef: required)
587588
588589opt_model.deeper options:
589590 default: null (undefined)
590591
591- --opt_model.deeper {{JSON,null}}
592- set opt_model.deeper from JSON string
592+ --opt_model.deeper [ {{JSON,null}}]
593+ set opt_model.deeper from JSON string (default: {{}})
593594 --opt_model.deeper.flag bool
594595 (ifdef: required)
595596
596597fact_model options:
597- --fact_model JSON set fact_model from JSON string
598+ --fact_model [ JSON] set fact_model from JSON string (default: {{}})
598599 --fact_model.flag bool
599600 (default factory: <lambda>)
600601
601602fact_model.deep options:
602- --fact_model.deep JSON
603- set fact_model.deep from JSON string
603+ --fact_model.deep [ JSON]
604+ set fact_model.deep from JSON string (default: {{}})
604605 --fact_model.deep.flag bool
605606 (default factory: <lambda>)
606607
607608fact_model.deep.deeper options:
608- --fact_model.deep.deeper {{JSON,null}}
609- set fact_model.deep.deeper from JSON string
609+ --fact_model.deep.deeper [{{JSON,null}}]
610+ set fact_model.deep.deeper from JSON string (default:
611+ {{}})
610612 --fact_model.deep.deeper.flag bool
611613 (default factory: <lambda>)
612614"""
@@ -1529,13 +1531,13 @@ class Settings(BaseSettings):
15291531
15301532 assert (
15311533 capsys .readouterr ().out
1532- == f"""usage: example.py [-h] [--sub_model JSON] [--sub_model.v1 int]
1534+ == f"""usage: example.py [-h] [--sub_model [ JSON] ] [--sub_model.v1 int]
15331535
15341536{ ARGPARSE_OPTIONS_TEXT } :
15351537 -h, --help show this help message and exit
15361538
15371539sub_model options:
1538- --sub_model JSON set sub_model from JSON string
1540+ --sub_model [ JSON] set sub_model from JSON string (default: {{}})
15391541 --sub_model.v1 int (required)
15401542"""
15411543 )
@@ -1573,13 +1575,13 @@ class Settings(BaseSettings):
15731575
15741576 assert (
15751577 capsys .readouterr ().out
1576- == f"""usage: example.py [-h] [--sub_model JSON]
1578+ == f"""usage: example.py [-h] [--sub_model [ JSON] ]
15771579
15781580{ ARGPARSE_OPTIONS_TEXT } :
1579- -h, --help show this help message and exit
1581+ -h, --help show this help message and exit
15801582
15811583sub_model options:
1582- --sub_model JSON set sub_model from JSON string
1584+ --sub_model [ JSON] set sub_model from JSON string (default: {{}})
15831585"""
15841586 )
15851587
@@ -1653,7 +1655,7 @@ class Settings(BaseSettings):
16531655
16541656 assert (
16551657 capsys .readouterr ().out
1656- == f"""usage: example.py [-h] [--sub_model JSON] [--sub_model.v1 int]
1658+ == f"""usage: example.py [-h] [--sub_model [ JSON] ] [--sub_model.v1 int]
16571659
16581660My application help text.
16591661
@@ -1663,7 +1665,7 @@ class Settings(BaseSettings):
16631665sub_model options:
16641666 The help text from the field description
16651667
1666- --sub_model JSON set sub_model from JSON string
1668+ --sub_model [ JSON] set sub_model from JSON string (default: {{}})
16671669 --sub_model.v1 int (required)
16681670"""
16691671 )
@@ -1673,7 +1675,7 @@ class Settings(BaseSettings):
16731675
16741676 assert (
16751677 capsys .readouterr ().out
1676- == f"""usage: example.py [-h] [--sub_model JSON] [--sub_model.v1 int]
1678+ == f"""usage: example.py [-h] [--sub_model [ JSON] ] [--sub_model.v1 int]
16771679
16781680My application help text.
16791681
@@ -1683,7 +1685,7 @@ class Settings(BaseSettings):
16831685sub_model options:
16841686 The help text from the class docstring
16851687
1686- --sub_model JSON set sub_model from JSON string
1688+ --sub_model [ JSON] set sub_model from JSON string (default: {{}})
16871689 --sub_model.v1 int (required)
16881690"""
16891691 )
@@ -2411,3 +2413,17 @@ class Root(BaseModel):
24112413 --deep-arg str (required)
24122414"""
24132415 )
2416+
2417+
2418+ def test_cli_json_optional_default ():
2419+ class Nested (BaseModel ):
2420+ foo : int = 1
2421+ bar : int = 2
2422+
2423+ class Options (BaseSettings ):
2424+ nested : Nested = Nested (foo = 3 , bar = 4 )
2425+
2426+ assert CliApp .run (Options , cli_args = []).model_dump () == {'nested' : {'foo' : 3 , 'bar' : 4 }}
2427+ assert CliApp .run (Options , cli_args = ['--nested' ]).model_dump () == {'nested' : {'foo' : 1 , 'bar' : 2 }}
2428+ assert CliApp .run (Options , cli_args = ['--nested={}' ]).model_dump () == {'nested' : {'foo' : 1 , 'bar' : 2 }}
2429+ assert CliApp .run (Options , cli_args = ['--nested.foo=5' ]).model_dump () == {'nested' : {'foo' : 5 , 'bar' : 2 }}
0 commit comments