Skip to content
Merged
14 changes: 13 additions & 1 deletion monai/bundle/config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def __setitem__(self, id: Union[str, int], config: Any):
# get the last parent level config item and replace it
last_id = ID_SEP_KEY.join(keys[:-1])
conf_ = self[last_id]

indexing = keys[-1] if isinstance(conf_, dict) else int(keys[-1])
conf_[indexing] = config
self.ref_resolver.reset()
Expand All @@ -176,15 +177,26 @@ def get(self, id: str = "", default: Optional[Any] = None):
except (KeyError, IndexError): # Index error for integer indexing
return default

def set(self, config: Any, id: str = ""):
def set(self, config: Any, id: str = "", recursive: bool = True):
"""
Set config by ``id``.

Args:
config: config to set at location ``id``.
id: id to specify the expected position. See also :py:meth:`__setitem__`.
recursive: if the nested id doesn't exist, whether to recursively create the nested items in the config.
default to `True`. for the nested id, only support `dict` for the missing section.

"""
keys = str(id).split(ID_SEP_KEY)
conf_ = self.get()
if recursive:
if conf_ is None:
self.config = conf_ = {} # type: ignore
for k in keys[:-1]:
if isinstance(conf_, dict) and k not in conf_:
conf_[k] = {}
conf_ = conf_[k if isinstance(conf_, dict) else int(k)]
self[id] = config

def update(self, pairs: Dict[str, Any]):
Expand Down
8 changes: 7 additions & 1 deletion tests/test_config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,15 @@ def test_parse(self, config, expected_ids, output_types):
self.assertEqual(trans, parser.get_parsed_content(id="transform#transforms#0"))
self.assertEqual(trans, parser.get_parsed_content(id="transform#transforms#0", lazy=True))
self.assertNotEqual(trans, parser.get_parsed_content(id="transform#transforms#0", lazy=False))
# test nested id
# test new nested id
parser.set("fake_key", "transform#other_transforms#keys", True)
self.assertEqual(parser.get(id="transform#other_transforms#keys"), "fake_key")
# remove temp fake data
parser["transform"].pop("other_transforms")
# test update nested id
parser["transform#transforms#0#keys"] = "label2"
self.assertEqual(parser.get_parsed_content(id="transform#transforms#0").keys[0], "label2")

for id, cls in zip(expected_ids, output_types):
self.assertTrue(isinstance(parser.get_parsed_content(id), cls))
# test root content
Expand Down