Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow configuration aliases #255

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion jsonargparse/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -746,3 +762,8 @@ def handle_subcommands(
# Handle inner subcommands
if subparser._subparsers is not None:
_ActionSubCommands.handle_subcommands(subparser, cfg, env, defaults, key+'.', fail_no_subcommand=fail_no_subcommand)


def get_alias_dest(action):
return [optstr.lstrip('-').replace('-', '_')
for optstr in action.option_strings]
20 changes: 19 additions & 1 deletion jsonargparse/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,25 @@ def _apply_actions(
continue

action_dest = action.dest if subcommand is None else subcommand+'.'+action.dest
value = cfg[action_dest]
ALLOW_ALIAS = 1
try:
value = cfg[action_dest]
except KeyError:
from jsonargparse.actions import get_alias_dest
if ALLOW_ALIAS:
# 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):
if alias in cfg:
value = cfg[alias]
found = True
break
if not found:
raise
else:
raise
...
Fixed Show fixed Hide fixed
if skip_fn and skip_fn(value):
continue
with parser_context(parent_parser=self, lenient_check=True):
Expand Down
17 changes: 17 additions & 0 deletions jsonargparse_tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,5 +1223,22 @@ def test_add_multiple_config_arguments_error(self):
parser.add_argument('--cfg2', action=ActionConfigFile)


def test_parser_alias(self):
import jsonargparse
Fixed Show fixed Hide fixed

# Create a parser where --bar is an alias for --foo
parser = jsonargparse.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)