diff --git a/jsonargparse/actions.py b/jsonargparse/actions.py index 9cdf6ec2..b352d2cc 100644 --- a/jsonargparse/actions.py +++ b/jsonargparse/actions.py @@ -39,6 +39,19 @@ class Action(LoggerProperty, ArgparseAction): """Base for jsonargparse Action classes.""" + @property + def aliases(self): + return _action_aliases(self) + + +def _action_aliases(self): + if not hasattr(self, '_aliases'): + options = {optstr.lstrip('-').replace('-', '_') + for optstr in self.option_strings} + options = {opt for opt in options if len(opt) > 1} + self._aliases = {self.dest} | options + return self._aliases + def _is_branch_key(parser, key: str) -> bool: root_key = split_key_root(key)[0] @@ -69,8 +82,11 @@ def _find_action_and_subcommand( if exclude is not None: actions = [a for a in actions if not isinstance(a, exclude)] fallback_action = None + for action in actions: - if action.dest == dest: + # _StoreAction seems to break the property + # if dest in action.aliases: + if dest in _action_aliases(action): if isinstance(action, _ActionConfigLoad): fallback_action = action else: diff --git a/jsonargparse/core.py b/jsonargparse/core.py index 48333828..523286ad 100644 --- a/jsonargparse/core.py +++ b/jsonargparse/core.py @@ -1254,7 +1254,22 @@ def _apply_actions( continue action_dest = action.dest if subcommand is None else subcommand+'.'+action.dest - value = cfg[action_dest] + try: + value = cfg[action_dest] + except KeyError: + from jsonargparse.actions import _action_aliases + + # If the main key isn't in the config, check if it exists + # under an alias. + found = None + # for alias in get_alias_dest(action): + for alias in _action_aliases(action): + if alias in cfg: + value = cfg[alias] + found = True + break + if not found: + raise if skip_fn and skip_fn(value): continue with parser_context(parent_parser=self, lenient_check=True): diff --git a/jsonargparse_tests/test_core.py b/jsonargparse_tests/test_core.py index b76dfe14..608a20f7 100755 --- a/jsonargparse_tests/test_core.py +++ b/jsonargparse_tests/test_core.py @@ -1223,5 +1223,26 @@ def test_add_multiple_config_arguments_error(self): parser.add_argument('--cfg2', action=ActionConfigFile) + def test_parser_alias(self): + # TODO: + # Successful parsing of a value in an alias saved as the dest key and the alias not appearing in the namespace. + # Failure to parse alias because the value does not agree with the argument type. + # Alias in a nested namespace. + # Alias with name that includes dashes -. + + # Create a parser where --bar is an alias for --foo + parser = ArgumentParser() + parser.add_argument('--foo', '--bar') + + parsed = parser.parse_string('foo: "aaa"') + assert parsed.foo == 'aaa' + + parsed = parser.parse_string('bar: "bbb"') + assert parsed.foo == 'bbb' + + parsed = parser.parse_args(['--bar', 'ccc']) + assert parsed.foo == 'ccc' + + if __name__ == '__main__': unittest.main(verbosity=2)