From c5626548b4b639824e76856de667f4992cd14b53 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Wed, 10 Apr 2019 23:44:08 -0700 Subject: [PATCH 01/13] git: Ignore new-style .eggs/ directories. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5cef09f2..5b14ec25 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,5 @@ docs/_build # IDEs .idea + +.eggs/ From a8960d60223fc153b813a728a5a69e9394eefd01 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Wed, 10 Apr 2019 23:45:45 -0700 Subject: [PATCH 02/13] configargparse: Prepend env var and config args so they don't break subcommands. --- configargparse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configargparse.py b/configargparse.py index d26d88fc..8b41c15c 100644 --- a/configargparse.py +++ b/configargparse.py @@ -445,7 +445,7 @@ def parse_known_args(self, args = None, namespace = None, env_var_args += self.convert_item_to_command_line_arg( action, key, value) - args = args + env_var_args + args = env_var_args + args if env_var_args: self._source_to_settings[_ENV_VAR_SOURCE_KEY] = OrderedDict( @@ -504,7 +504,7 @@ def parse_known_args(self, args = None, namespace = None, self._source_to_settings[source_key] = OrderedDict() self._source_to_settings[source_key][key] = (action, value) - args = args + config_args + args = config_args + args # save default settings for use by print_values() From bf1dbedcf5f238476d7fdaf2a455fc43066f5880 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 01:49:17 -0700 Subject: [PATCH 03/13] configargparse: Account for nargs edge case. --- configargparse.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/configargparse.py b/configargparse.py index 8b41c15c..63899e9f 100644 --- a/configargparse.py +++ b/configargparse.py @@ -431,6 +431,7 @@ def parse_known_args(self, args = None, namespace = None, # add env var settings to the commandline that aren't there already env_var_args = [] + 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)] @@ -439,20 +440,23 @@ def parse_known_args(self, args = None, namespace = None, value = env_vars[key] # Make list-string into list. if action.nargs or isinstance(action, argparse._AppendAction): + nargs = True element_capture = re.match('\[(.*)\]', value) if element_capture: value = [val.strip() for val in element_capture.group(1).split(',') if val.strip()] env_var_args += self.convert_item_to_command_line_arg( action, key, value) - args = env_var_args + args + if nargs: + args = args + env_var_args + else: + args = env_var_args + args if env_var_args: self._source_to_settings[_ENV_VAR_SOURCE_KEY] = OrderedDict( [(a.env_var, (a, env_vars[a.env_var])) for a in actions_with_env_var_values]) - # before parsing any config files, check if -h was specified. supports_help_arg = any( a for a in self._actions if isinstance(a, argparse._HelpAction)) @@ -484,6 +488,7 @@ def parse_known_args(self, args = None, namespace = None, # add each config item to the commandline unless it's there already config_args = [] + nargs = False for key, value in config_items.items(): if key in known_config_keys: action = known_config_keys[key] @@ -503,9 +508,14 @@ def parse_known_args(self, args = None, namespace = None, if source_key not in self._source_to_settings: self._source_to_settings[source_key] = OrderedDict() self._source_to_settings[source_key][key] = (action, value) + if (action and action.nargs or + isinstance(action, argparse._AppendAction)): + nargs = True - args = config_args + args - + if nargs: + args = args + config_args + else: + args = config_args + args # save default settings for use by print_values() default_settings = OrderedDict() From b23a058ed05c95107ad2853bdb0ea9f268429b13 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 01:51:20 -0700 Subject: [PATCH 04/13] travis: Add latest Python versions. --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index aaea88af..62a7fa9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,8 @@ language: python python: + - "3.7" + - "3.6" - "3.5" - "3.4" - "3.3" @@ -10,6 +12,7 @@ python: - "2.7" - "2.6" - "pypy" + - "pypy3" # command to install dependencies: install: pip install mock @@ -18,4 +21,4 @@ install: pip install mock script: python setup.py test # migrate to container-based travis.ci: http://docs.travis-ci.com/user/migrating-from-legacy -sudo: false \ No newline at end of file +sudo: false From 75ab8d2e379b1241be5063aafdc92c1e6f23435b Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 01:53:51 -0700 Subject: [PATCH 05/13] travis: Python 3.7 is on Xenial. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 62a7fa9d..a84a3dee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ # Config file for automatic testing at travis-ci.org language: python - +dist: xenial # Needed for Python 3.7 python: - "3.7" - "3.6" From 9e2fa6fc63ae20ae5f9f4581f10dd1cafbbb354c Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 02:00:41 -0700 Subject: [PATCH 06/13] travis: Fix build matrix. --- .travis.yml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index a84a3dee..f51a063b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,20 @@ # Config file for automatic testing at travis-ci.org language: python -dist: xenial # Needed for Python 3.7 -python: - - "3.7" - - "3.6" - - "3.5" - - "3.4" - - "3.3" - - "3.2" - - "2.7" - - "2.6" - - "pypy" - - "pypy3" +matrix: + - dist: xenial # Needed for Python 3.7 + python: + - "3.7" + - "3.6" + - python: + - "3.5" + - "3.4" + - "3.3" + - "3.2" + - "2.7" + - "2.6" + - "pypy" + - "pypy3" # command to install dependencies: install: pip install mock From 1228a3789b57b076f7267772ac9e42595a8ac83d Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 02:06:22 -0700 Subject: [PATCH 07/13] tox: Update with latest Python versions. --- tox.ini | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 0323345e..a21a059a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26, py27, py32, py33, py34, py35 +envlist = py26, py27, py32, py33, py34, py35, py36, py37, pypy, pypy3 # py34 # bug with virtualenv so tox doesn't work? @@ -27,5 +27,14 @@ basepython=python3.4 [testenv:py35] basepython=python3.5 +[testenv:py36] +basepython=python3.6 + +[testenv:py37] +basepython=python3.7 + [testenv:pypy] basepython=pypy + +[testenv:pypy3] +basepython=pypy3 From c67b2e669c006c79ead88eabf7fde336de738d58 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 02:11:44 -0700 Subject: [PATCH 08/13] travis: Fix matrix, probably. --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f51a063b..7611b768 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,13 @@ # Config file for automatic testing at travis-ci.org -language: python matrix: - dist: xenial # Needed for Python 3.7 + language: python python: - "3.7" - "3.6" - - python: + - language: python + python: - "3.5" - "3.4" - "3.3" From 46371c958a50e3fefa69dc098f1419d73912a755 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 02:25:51 -0700 Subject: [PATCH 09/13] configargparse,test: Positional args to ArgumentParser should work too. --- configargparse.py | 3 ++- tests/test_configargparse.py | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/configargparse.py b/configargparse.py index 63899e9f..2a2c5172 100644 --- a/configargparse.py +++ b/configargparse.py @@ -266,6 +266,7 @@ class ArgumentParser(argparse.ArgumentParser): """ def __init__(self, + *args, add_config_file_help=True, add_env_var_help=True, auto_env_var_prefix=None, @@ -335,7 +336,7 @@ def __init__(self, self._add_env_var_help = add_env_var_help self._auto_env_var_prefix = auto_env_var_prefix - argparse.ArgumentParser.__init__(self, **kwargs) + argparse.ArgumentParser.__init__(self, *args, **kwargs) # parse the additional args if config_file_parser_class is None: diff --git a/tests/test_configargparse.py b/tests/test_configargparse.py index c22a3622..114e5cd8 100644 --- a/tests/test_configargparse.py +++ b/tests/test_configargparse.py @@ -755,6 +755,14 @@ def test_FormatHelp(self): '--flag \s*Flag help text' ) + def test_FormatHelpProg(self): + self.initParser('format_help_prog') + self.assertRegex(self.format_help(), 'usage: format_help_prog .*') + + def test_FormatHelpProgLib(self): + parser = argparse.ArgumentParser('format_help_prog') + self.assertRegex(parser.format_help(), 'usage: format_help_prog .*') + class CustomClass(object): def __init__(self, name): self.name = name From c80ffc2c4ade1ad02797f42fa12707f9826393a4 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 02:29:01 -0700 Subject: [PATCH 10/13] travis: Tryna fix the matrix. --- .travis.yml | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7611b768..fa8f27f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,19 @@ # Config file for automatic testing at travis-ci.org matrix: + include: - dist: xenial # Needed for Python 3.7 - language: python - python: - - "3.7" - - "3.6" - - language: python - python: - - "3.5" - - "3.4" - - "3.3" - - "3.2" - - "2.7" - - "2.6" - - "pypy" - - "pypy3" + python: 3.7 + - dist: xenial # Needed for Python 3.6 + python: 3.6 + - python: 3.5 + - python: 3.4 + - python: 3.3 + - python: 3.2 + - python: 2.7 + - python: 2.6 + - python: pypy + - python: pypy3 # command to install dependencies: install: pip install mock From 92c598934ccb274008bf0353a48e26cdfc238f65 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 02:31:08 -0700 Subject: [PATCH 11/13] travis: Neo, I am not. --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index fa8f27f8..e01dcea7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,26 @@ matrix: include: - dist: xenial # Needed for Python 3.7 python: 3.7 + language: python - dist: xenial # Needed for Python 3.6 python: 3.6 + language: python - python: 3.5 + language: python - python: 3.4 + language: python - python: 3.3 + language: python - python: 3.2 + language: python - python: 2.7 + language: python - python: 2.6 + language: python - python: pypy + language: python - python: pypy3 + language: python # command to install dependencies: install: pip install mock From f67027ac8b5eae9303b07f30020f5f5b1f0abd33 Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 11:28:42 -0700 Subject: [PATCH 12/13] configargparse: Python 2/3 compatible style keyword arguments and positional args. --- configargparse.py | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/configargparse.py b/configargparse.py index 2a2c5172..0389f7ac 100644 --- a/configargparse.py +++ b/configargparse.py @@ -265,23 +265,7 @@ class ArgumentParser(argparse.ArgumentParser): environment variables and .ini or .yaml-style config files. """ - def __init__(self, - *args, - add_config_file_help=True, - add_env_var_help=True, - auto_env_var_prefix=None, - default_config_files=[], - ignore_unknown_config_file_keys=False, - config_file_parser_class=DefaultConfigFileParser, - args_for_setting_config_path=[], - config_arg_is_required=False, - config_arg_help_message="config file path", - args_for_writing_out_config_file=[], - write_out_config_file_arg_help_message="takes the current command line " - "args and writes them out to a config file at the given path, then " - "exits", - **kwargs - ): + def __init__(self, *args, **kwargs): """Supports args of the argparse.ArgumentParser constructor as **kwargs, as well as the following additional args. @@ -332,6 +316,29 @@ def __init__(self, write_out_config_file_arg_help_message: The help message to use for the args in args_for_writing_out_config_file. """ + # This is the only way to make positional args (tested in the argparse + # main test suite) and keyword arguments work across both Python 2 and + # 3. This could be refactored to not need extra local variables. + add_config_file_help = kwargs.pop('add_config_file_help', True) + add_env_var_help = kwargs.pop('add_env_var_help', True) + auto_env_var_prefix = kwargs.pop('auto_env_var_prefix', None) + default_config_files = kwargs.pop('default_config_files', []) + ignore_unknown_config_file_keys = kwargs.pop( + 'ignore_unknown_config_file_keys', False) + config_file_parser_class = kwargs.pop('config_file_parser_class', + DefaultConfigFileParser) + args_for_setting_config_path = kwargs.pop( + 'args_for_setting_config_path', []) + config_arg_is_required = kwargs.pop('config_arg_is_required', False) + config_arg_help_message = kwargs.pop('config_arg_help_message', + "config file path") + args_for_writing_out_config_file = kwargs.pop( + 'args_for_writing_out_config_file', []) + write_out_config_file_arg_help_message = kwargs.pop( + 'write_out_config_file_arg_help_message', "takes the current " + "command line args and writes them out to a config file at the " + "given path, then exits") + self._add_config_file_help = add_config_file_help self._add_env_var_help = add_env_var_help self._auto_env_var_prefix = auto_env_var_prefix From 1d55ace12f80243d85f5702c3fdbea282d906bab Mon Sep 17 00:00:00 2001 From: Jacob Alheid Date: Thu, 11 Apr 2019 22:35:39 -0700 Subject: [PATCH 13/13] setup: Bump version for conflict avoidance. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1af424ec..553033ae 100644 --- a/setup.py +++ b/setup.py @@ -84,7 +84,7 @@ def launch_http_server(directory): setup( name='ConfigArgParse', - version="0.14.0", + version="0.14.1", 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,