Skip to content

Commit

Permalink
Merge pull request #166 from Savlik/issue-137
Browse files Browse the repository at this point in the history
Dash supported as first char of argument
  • Loading branch information
bw2 authored Dec 8, 2019
2 parents 329afa4 + 1fc2452 commit d10b34f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 28 deletions.
45 changes: 21 additions & 24 deletions configargparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,17 +397,6 @@ def parse_known_args(self, args = None, namespace = None,
else:
args = list(args)

# normalize args by converting args like --key=value to --key value
normalized_args = []
for arg in args:
if arg and arg[0] in self.prefix_chars and '=' in arg:
key, value = arg.split('=', 1)
normalized_args.append(key)
normalized_args.append(value)
else:
normalized_args.append(arg)
args = normalized_args

for a in self._actions:
a.is_positional_arg = not a.option_strings

Expand Down Expand Up @@ -438,7 +427,7 @@ def parse_known_args(self, args = None, namespace = None,
nargs = False
actions_with_env_var_values = [a for a in self._actions
if not a.is_positional_arg and a.env_var and a.env_var in env_vars
and not already_on_command_line(args, a.option_strings)]
and not already_on_command_line(args, a.option_strings, self.prefix_chars)]
for action in actions_with_env_var_values:
key = action.env_var
value = env_vars[key]
Expand Down Expand Up @@ -497,13 +486,14 @@ def parse_known_args(self, args = None, namespace = None,
if key in known_config_keys:
action = known_config_keys[key]
discard_this_key = already_on_command_line(
args, action.option_strings)
args, action.option_strings, self.prefix_chars)
else:
action = None
discard_this_key = self._ignore_unknown_config_file_keys or \
already_on_command_line(
args,
[self.get_command_line_key_for_unknown_config_file_setting(key)])
[self.get_command_line_key_for_unknown_config_file_setting(key)],
self.prefix_chars)

if not discard_this_key:
config_args += self.convert_item_to_command_line_arg(
Expand All @@ -526,7 +516,7 @@ def parse_known_args(self, args = None, namespace = None,
for action in self._actions:
cares_about_default_value = (not action.is_positional_arg or
action.nargs in [OPTIONAL, ZERO_OR_MORE])
if (already_on_command_line(args, action.option_strings) or
if (already_on_command_line(args, action.option_strings, self.prefix_chars) or
not cares_about_default_value or
action.default is None or
action.default == SUPPRESS or
Expand Down Expand Up @@ -617,7 +607,8 @@ def get_items_for_config_file_output(self, source_to_settings,
config_file_keys = self.get_possible_config_keys(action)
if config_file_keys and not action.is_positional_arg and \
already_on_command_line(existing_command_line_args,
action.option_strings):
action.option_strings,
self.prefix_chars):
value = getattr(parsed_namespace, action.dest, None)
if value is not None:
if isinstance(value, bool):
Expand Down Expand Up @@ -675,8 +666,7 @@ def convert_item_to_command_line_arg(self, action, key, value):
elif isinstance(value, list):
if action is None or isinstance(action, argparse._AppendAction):
for list_elem in value:
args.append( command_line_key )
args.append( str(list_elem) )
args.append( "%s=%s" % (command_line_key, str(list_elem)) )
elif (isinstance(action, argparse._StoreAction) and action.nargs in ('+', '*')) or (
isinstance(action.nargs, int) and action.nargs > 1):
args.append( command_line_key )
Expand All @@ -686,8 +676,7 @@ def convert_item_to_command_line_arg(self, action, key, value):
self.error(("%s can't be set to a list '%s' unless its action type is changed "
"to 'append' or nargs is set to '*', '+', or > 1") % (key, value))
elif isinstance(value, str):
args.append( command_line_key )
args.append( value )
args.append( "%s=%s" % (command_line_key, value) )
else:
raise ValueError("Unexpected value type {} for value: {}".format(
type(value), value))
Expand Down Expand Up @@ -719,7 +708,7 @@ def _open_config_files(self, command_line_args):
constructor that are present on disk.
Args:
command_line_args: List of all args (already split on spaces)
command_line_args: List of all args
"""
# open any default config files
config_files = [open(f) for files in map(glob.glob, map(os.path.expanduser, self._default_config_files))
Expand Down Expand Up @@ -909,13 +898,21 @@ def add_argument(self, *args, **kwargs):
return action


def already_on_command_line(existing_args_list, potential_command_line_args):
def already_on_command_line(existing_args_list, potential_command_line_args, prefix_chars):
"""Utility method for checking if any of the potential_command_line_args is
already present in existing_args.
"""
return any(potential_arg in existing_args_list
for potential_arg in potential_command_line_args)
arg_names = []
for arg_string in existing_args_list:
if arg_string and arg_string[0] in prefix_chars and "=" in arg_string :
option_string, explicit_arg = arg_string.split("=", 1)
arg_names.append(option_string)
else:
arg_names.append(arg_string)

return any(
potential_arg in arg_names for potential_arg in potential_command_line_args
)


# wrap ArgumentParser's add_argument(..) method with the one above
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def launch_http_server(directory):

setup(
name='ConfigArgParse',
version="0.15.1",
version="0.15.2",
description='A drop-in replacement for argparse that allows options to '
'also be set via config files and/or environment variables.',
long_description=long_description,
Expand Down
68 changes: 65 additions & 3 deletions tests/test_configargparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,12 +460,12 @@ def testConfigFileSyntax(self):
ns, args = self.parse_known("-x 10 --y 3.8",
config_file_contents="bla=3",
env_vars={"bla": "2"})
self.assertListEqual(args, ["--bla", "3"])
self.assertListEqual(args, ["--bla=3"])

self.initParser(ignore_unknown_config_file_keys=False)
ns, args = self.parse_known(args="-x 1", config_file_contents="bla=3",
env_vars={"bla": "2"})
self.assertEqual(set(args), {"--bla", "3", "-x", "1"})
self.assertEqual(set(args), {"--bla=3", "-x", "1"})

def testBooleanValuesCanBeExpressedAsNumbers(self):
self.initParser()
Expand Down Expand Up @@ -542,6 +542,68 @@ def testConfigOrEnvValueErrors(self):
ns = self.parse("", env_vars = {"file": "[1,2,3]", "VERBOSE": "true"})
self.assertIsNone(ns.file)

def testValuesStartingWithDash(self):
self.initParser()
self.add_arg("--arg0")
self.add_arg("--arg1", env_var="ARG1")
self.add_arg("--arg2")
self.add_arg("--arg3", action='append')
self.add_arg("--arg4", action='append', env_var="ARG4")
self.add_arg("--arg5", action='append')

ns = self.parse(
"--arg0=-foo --arg3=-foo --arg3=-bar",
config_file_contents="arg2: -foo\narg5: [-foo, -bar]",
env_vars={"ARG1": "-foo", "ARG4": "[-foo, -bar]"}
)
self.assertEqual(ns.arg0, "-foo")
self.assertEqual(ns.arg1, "-foo")
self.assertEqual(ns.arg2, "-foo")
self.assertEqual(ns.arg3, ["-foo", "-bar"])
self.assertEqual(ns.arg4, ["-foo", "-bar"])
self.assertEqual(ns.arg5, ["-foo", "-bar"])

def testPriorityKnown(self):
self.initParser()
self.add_arg("--arg", env_var="ARG")

ns = self.parse(
"--arg command_line_val",
config_file_contents="arg: config_val",
env_vars={"ARG": "env_val"}
)
self.assertEqual(ns.arg, "command_line_val")

ns = self.parse(
"--arg=command_line_val",
config_file_contents="arg: config_val",
env_vars={"ARG": "env_val"}
)
self.assertEqual(ns.arg, "command_line_val")

ns = self.parse(
"",
config_file_contents="arg: config_val",
env_vars={"ARG": "env_val"}
)
self.assertEqual(ns.arg, "env_val")

def testPriorityUnknown(self):
self.initParser()

ns, args = self.parse_known(
"--arg command_line_val",
config_file_contents="arg: config_val",
env_vars={"arg": "env_val"}
)
self.assertListEqual(args, ["--arg", "command_line_val"])

ns, args = self.parse_known(
"--arg=command_line_val",
config_file_contents="arg: config_val",
)
self.assertListEqual(args, ["--arg=command_line_val"])

def testAutoEnvVarPrefix(self):
self.initParser(auto_env_var_prefix="TEST_")
self.add_arg("-a", "--arg0", is_config_file_arg=True)
Expand Down Expand Up @@ -719,7 +781,7 @@ def test_AbbrevConfigFileArgs(self):

known, unknown = self.parse_known(command)

self.assertListEqual(unknown, ['--a2a', '0.5', '--a3a', '0.5'])
self.assertListEqual(unknown, ['--a2a=0.5', '--a3a=0.5'])

def test_FormatHelp(self):
self.initParser(args_for_setting_config_path=["-c", "--config"],
Expand Down

0 comments on commit d10b34f

Please sign in to comment.