Skip to content

Commit

Permalink
Fix failures with subcommands and default_config_files when keys are …
Browse files Browse the repository at this point in the history
…repeated (#160).
  • Loading branch information
mauvilsa committed Oct 11, 2023
1 parent 863be75 commit f693b7e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ The semantic versioning only considers the public API as described in
paths are considered internals and can change in minor and patch releases.


v4.25.1 (2023-10-??)
--------------------

Fixed
^^^^^
- Failures with subcommands and default_config_files when keys are repeated
(`#160 <https://github.com/omni-us/jsonargparse/issues/160>`__).


v4.25.0 (2023-09-25)
--------------------

Expand Down
7 changes: 4 additions & 3 deletions jsonargparse/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ def _load_config_parser_mode(
cfg_path: Union[str, os.PathLike] = "",
ext_vars: Optional[dict] = None,
prev_cfg: Optional[Namespace] = None,
key: Optional[str] = None,
) -> Namespace:
"""Loads a configuration string into a namespace.
Expand All @@ -633,6 +634,8 @@ def _load_config_parser_mode(
raise TypeError(f"Problems parsing config: {ex}") from ex
if cfg_dict is None:
return Namespace()
if key and isinstance(cfg_dict, dict):
cfg_dict = cfg_dict.get(key, {})
if not isinstance(cfg_dict, dict):
raise TypeError(f"Unexpected config: {cfg_str}")
return self._apply_actions(cfg_dict, prev_cfg=prev_cfg)
Expand Down Expand Up @@ -954,9 +957,7 @@ def get_defaults(self, skip_check: bool = False) -> Namespace:
default_config_files = self._get_default_config_files()
for key, default_config_file in default_config_files:
with change_to_path_dir(default_config_file), parser_context(parent_parser=self):
cfg_file = self._load_config_parser_mode(default_config_file.get_content())
if key is not None:
cfg_file = cfg_file.get(key)
cfg_file = self._load_config_parser_mode(default_config_file.get_content(), key=key)
cfg = self.merge_config(cfg_file, cfg)
try:
with _ActionPrintConfig.skip_print_config():
Expand Down
31 changes: 31 additions & 0 deletions jsonargparse_tests/test_subcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,37 @@ def test_subcommand_print_config_default_env(subparser):
assert yaml.safe_load(out) == {"o": 1}


def test_subcommand_default_config_repeated_keys(parser, subparser, tmp_cwd):
defaults = tmp_cwd / "defaults.json"
defaults.write_text('{"test":{"test":"value"}}')
parser.default_config_files = [defaults]
subparser.add_argument("--test")
subcommands = parser.add_subcommands()
subcommands.add_subcommand("test", subparser)

cfg = parser.parse_args([], with_meta=False)
assert cfg == Namespace(subcommand="test", test=Namespace(test="value"))
cfg = parser.parse_args(["test", "--test=x"], with_meta=False)
assert cfg == Namespace(subcommand="test", test=Namespace(test="x"))


def test_subsubcommand_default_config_repeated_keys(parser, subparser, tmp_cwd):
defaults = tmp_cwd / "defaults.json"
defaults.write_text('{"test":{"test":{"test":"value"}}}')
parser.default_config_files = [defaults]
subsubparser = ArgumentParser()
subsubparser.add_argument("--test")
subcommands1 = parser.add_subcommands()
subcommands1.add_subcommand("test", subparser)
subcommands2 = subparser.add_subcommands()
subcommands2.add_subcommand("test", subsubparser)

cfg = parser.parse_args([], with_meta=False)
assert cfg.as_dict() == {"subcommand": "test", "test": {"subcommand": "test", "test": {"test": "value"}}}
cfg = parser.parse_args(["test", "test", "--test=x"], with_meta=False)
assert cfg.as_dict() == {"subcommand": "test", "test": {"subcommand": "test", "test": {"test": "x"}}}


def test_subcommand_required_arg_in_default_config(parser, subparser, tmp_cwd):
Path("config.yaml").write_text("output: test\nprepare:\n media: test\n")
parser.default_config_files = ["config.yaml"]
Expand Down

0 comments on commit f693b7e

Please sign in to comment.