Skip to content

Commit b7efc86

Browse files
authored
Dict override syntax to allow standard form: --cfg.dict.key val (#824)
1 parent 10cfd30 commit b7efc86

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Added
2525

2626
Fixed
2727
^^^^^
28+
- Dict override syntax to allow standard form: --cfg.dict.key val (`#824
29+
<https://github.com/omni-us/jsonargparse/pull/824>`__).
2830
- Evaluation of postponed annotations for dataclass inheritance across modules
2931
not working correctly (`#814
3032
<https://github.com/omni-us/jsonargparse/pull/814>`__).

jsonargparse/_typehints.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,11 @@ def adapt_typehints(
919919
elif typehint_origin in mapping_origin_types:
920920
if isinstance(val, NestedArg):
921921
if isinstance(prev_val, dict):
922-
val = {**prev_val, val.key: val.val}
922+
if isinstance(val.key, str) and "." in val.key:
923+
key_prefix, key_suffix = val.key.split(".", 1)
924+
val = {**prev_val, key_prefix: {key_suffix: val.val}}
925+
else:
926+
val = {**prev_val, val.key: val.val}
923927
else:
924928
val = {val.key: val.val}
925929
elif isinstance(val, MappingProxyType):

jsonargparse_tests/test_typehints.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import uuid
99
from calendar import Calendar, TextCalendar
1010
from collections import OrderedDict
11-
from dataclasses import dataclass
11+
from dataclasses import dataclass, field
1212
from enum import Enum
1313
from pathlib import Path
1414
from types import MappingProxyType
@@ -580,6 +580,33 @@ def test_dict_command_line_set_items(parser):
580580
assert cfg.dict == {"one": 1, "two": 2}
581581

582582

583+
@dataclass
584+
class _Vals:
585+
val_0: int = 0
586+
val_1: int = 0
587+
588+
589+
@dataclass
590+
class _Cfg:
591+
"""Needs to be defined outside of test_nested_dict_command_line_set_items"""
592+
593+
vals: dict[str, _Vals] = field(default_factory=dict)
594+
595+
596+
def test_nested_dict_command_line_set_items(parser):
597+
parser.add_class_arguments(_Cfg, nested_key="cfg")
598+
599+
# works before #824
600+
args = ["--cfg", '{"vals": {"a": {"val_0": 0, "val_1": 1}}}', "--cfg.vals.a", '{"val_0": 100}']
601+
cfg = parser.parse_args(args).cfg
602+
assert (cfg.vals["a"].val_0, cfg.vals["a"].val_1) == (100, 1)
603+
604+
# does not work before #824
605+
args = ["--cfg", '{"vals": {"a": {"val_0": 0, "val_1": 1}}}', "--cfg.vals.a.val_0", "100"]
606+
cfg = parser.parse_args(args).cfg
607+
assert (cfg.vals["a"].val_0, cfg.vals["a"].val_1) == (100, 1)
608+
609+
583610
def test_dict_command_line_set_items_with_space(parser):
584611
parser.add_argument("--dict", type=dict)
585612
cfg = parser.parse_args(["--dict.a=x y"])

0 commit comments

Comments
 (0)