Set the action type when cloning an argument for a list index flag (#303).

This commit is contained in:
Dan Helfman
2025-03-27 12:42:49 -07:00
parent 50beb334dc
commit 79bf641668
3 changed files with 71 additions and 13 deletions
+11 -2
View File
@@ -362,9 +362,8 @@ def add_array_element_arguments(arguments_group, unparsed_arguments, flag_name):
pattern = re.compile(fr'^--{flag_name.replace("[0]", r"\[\d+\]").replace(".", r"\.")}$')
# Find an existing list index flag (and its action) corresponding to the given flag name. If one
# isn't found, bail.
try:
# Find an existing list index flag (and its action) corresponding to the given flag name.
(argument_action, existing_flag_name) = next(
(action, action_flag_name)
for action in arguments_group._group_actions
@@ -372,6 +371,15 @@ def add_array_element_arguments(arguments_group, unparsed_arguments, flag_name):
if pattern.match(action_flag_name)
if f'--{flag_name}'.startswith(action_flag_name)
)
# Based on the type of the action (e.g. argparse._StoreTrueAction), look up the corresponding
# action registry name (e.g., "store_true") to pass to add_argument(action=...) below.
action_registry_name = next(
registry_name
for registry_name, action_type in arguments_group._registries['action'].items()
# Not using isinstance() here because we only want an exact match—no parent classes.
if type(argument_action) == action_type
)
except StopIteration:
return
@@ -383,6 +391,7 @@ def add_array_element_arguments(arguments_group, unparsed_arguments, flag_name):
arguments_group.add_argument(
unparsed_flag_name,
action=action_registry_name,
choices=argument_action.choices,
default=argument_action.default,
dest=unparsed_flag_name.lstrip('-'),
@@ -20,11 +20,13 @@ def test_add_array_element_arguments_adds_arguments_for_array_index_flags():
arguments_group = parser.add_argument_group('arguments')
arguments_group.add_argument(
'--foo[0].val',
action='store_true',
dest='--foo[0].val',
)
flexmock(arguments_group).should_receive('add_argument').with_args(
'--foo[25].val',
action='store_true',
choices=object,
default=object,
dest='foo[25].val',
+58 -11
View File
@@ -672,13 +672,31 @@ def test_add_array_element_arguments_without_any_flags_bails():
)
# Use this instead of a flexmock because it's not easy to check the type() of a flexmock instance.
Group_action = collections.namedtuple(
'Group_action',
(
'option_strings',
'choices',
'default',
'nargs',
'required',
'type',
),
defaults=(
flexmock(), flexmock(), flexmock(), flexmock(), flexmock(),
)
)
def test_add_array_element_arguments_without_array_index_flags_bails():
arguments_group = flexmock(
_group_actions=(
flexmock(
Group_action(
option_strings=('--foo[0].val',),
),
)
),
_registries={'action': {'store_stuff': Group_action}},
)
arguments_group.should_receive('add_argument').never()
@@ -692,10 +710,11 @@ def test_add_array_element_arguments_without_array_index_flags_bails():
def test_add_array_element_arguments_with_non_matching_array_index_flags_bails():
arguments_group = flexmock(
_group_actions=(
flexmock(
Group_action(
option_strings=('--foo[0].val',),
),
)
),
_registries={'action': {'store_stuff': Group_action}},
)
arguments_group.should_receive('add_argument').never()
@@ -709,10 +728,11 @@ def test_add_array_element_arguments_with_non_matching_array_index_flags_bails()
def test_add_array_element_arguments_with_identical_array_index_flag_bails():
arguments_group = flexmock(
_group_actions=(
flexmock(
Group_action(
option_strings=('--foo[0].val',),
),
)
),
_registries={'action': {'store_stuff': Group_action}},
)
arguments_group.should_receive('add_argument').never()
@@ -723,10 +743,10 @@ def test_add_array_element_arguments_with_identical_array_index_flag_bails():
)
def test_add_array_element_arguments_adds_arguments_for_array_index_flags():
def test_add_array_element_arguments_without_action_type_in_registry_bails():
arguments_group = flexmock(
_group_actions=(
flexmock(
Group_action(
option_strings=('--foo[0].val',),
choices=flexmock(),
default=flexmock(),
@@ -734,10 +754,35 @@ def test_add_array_element_arguments_adds_arguments_for_array_index_flags():
required=flexmock(),
type=flexmock(),
),
)
),
_registries={'action': {'store_stuff': bool}},
)
arguments_group.should_receive('add_argument').never()
module.add_array_element_arguments(
arguments_group=arguments_group,
unparsed_arguments=('--foo[25].val', 'fooval', '--bar[1].val', 'barval'),
flag_name='foo[0].val',
)
def test_add_array_element_arguments_adds_arguments_for_array_index_flags():
arguments_group = flexmock(
_group_actions=(
Group_action(
option_strings=('--foo[0].val',),
choices=flexmock(),
default=flexmock(),
nargs=flexmock(),
required=flexmock(),
type=flexmock(),
),
),
_registries={'action': {'store_stuff': Group_action}},
)
arguments_group.should_receive('add_argument').with_args(
'--foo[25].val',
action='store_stuff',
choices=object,
default=object,
dest='foo[25].val',
@@ -756,7 +801,7 @@ def test_add_array_element_arguments_adds_arguments_for_array_index_flags():
def test_add_array_element_arguments_adds_arguments_for_array_index_flags_with_equals_sign():
arguments_group = flexmock(
_group_actions=(
flexmock(
Group_action(
option_strings=('--foo[0].val',),
choices=flexmock(),
default=flexmock(),
@@ -764,10 +809,12 @@ def test_add_array_element_arguments_adds_arguments_for_array_index_flags_with_e
required=flexmock(),
type=flexmock(),
),
)
),
_registries={'action': {'store_stuff': Group_action}},
)
arguments_group.should_receive('add_argument').with_args(
'--foo[25].val',
action='store_stuff',
choices=object,
default=object,
dest='foo[25].val',