Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-configargparse for
openSUSE:Factory checked in at 2021-07-12 01:25:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-configargparse (Old)
and /work/SRC/openSUSE:Factory/.python-configargparse.new.2625 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-configargparse"
Mon Jul 12 01:25:14 2021 rev:13 rq:905704 version:1.5.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-configargparse/python-configargparse.changes
2021-06-09 21:52:48.926529642 +0200
+++
/work/SRC/openSUSE:Factory/.python-configargparse.new.2625/python-configargparse.changes
2021-07-12 01:25:35.128978103 +0200
@@ -1,0 +2,6 @@
+Sun Jul 4 19:52:10 UTC 2021 - Dirk M??ller <[email protected]>
+
+- update to 1.5.1:
+ * no changes file available
+
+-------------------------------------------------------------------
Old:
----
ConfigArgParse-1.3.tar.gz
New:
----
ConfigArgParse-1.5.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-configargparse.spec ++++++
--- /var/tmp/diff_new_pack.Hace3N/_old 2021-07-12 01:25:35.500975243 +0200
+++ /var/tmp/diff_new_pack.Hace3N/_new 2021-07-12 01:25:35.504975212 +0200
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%bcond_without python2
Name: python-configargparse
-Version: 1.3
+Version: 1.5.1
Release: 0
Summary: A drop-in replacement for argparse
License: MIT
++++++ ConfigArgParse-1.3.tar.gz -> ConfigArgParse-1.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ConfigArgParse-1.3/ConfigArgParse.egg-info/PKG-INFO
new/ConfigArgParse-1.5.1/ConfigArgParse.egg-info/PKG-INFO
--- old/ConfigArgParse-1.3/ConfigArgParse.egg-info/PKG-INFO 2021-02-15
00:17:35.000000000 +0100
+++ new/ConfigArgParse-1.5.1/ConfigArgParse.egg-info/PKG-INFO 2021-07-01
15:11:14.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ConfigArgParse
-Version: 1.3
+Version: 1.5.1
Summary: A drop-in replacement for argparse that allows options to also be set
via config files and/or environment variables.
Home-page: https://github.com/bw2/ConfigArgParse
License: MIT
@@ -95,7 +95,7 @@
.. code:: py
- # settings for my_script.py
+ # settings for config_test.py
genome = HCMV # cytomegalovirus genome
dbsnp = /data/dbsnp/variants.vcf
@@ -486,7 +486,9 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
+Provides-Extra: test
Provides-Extra: yaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ConfigArgParse-1.3/ConfigArgParse.egg-info/SOURCES.txt
new/ConfigArgParse-1.5.1/ConfigArgParse.egg-info/SOURCES.txt
--- old/ConfigArgParse-1.3/ConfigArgParse.egg-info/SOURCES.txt 2021-02-15
00:17:36.000000000 +0100
+++ new/ConfigArgParse-1.5.1/ConfigArgParse.egg-info/SOURCES.txt
2021-07-01 15:11:14.000000000 +0200
@@ -10,5 +10,4 @@
ConfigArgParse.egg-info/top_level.txt
tests/__init__.py
tests/__init__.pyc
-tests/test_configargparse.py
-tests/test_configargparse.pyc
\ No newline at end of file
+tests/test_configargparse.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ConfigArgParse-1.3/ConfigArgParse.egg-info/requires.txt
new/ConfigArgParse-1.5.1/ConfigArgParse.egg-info/requires.txt
--- old/ConfigArgParse-1.3/ConfigArgParse.egg-info/requires.txt 2021-02-15
00:17:35.000000000 +0100
+++ new/ConfigArgParse-1.5.1/ConfigArgParse.egg-info/requires.txt
2021-07-01 15:11:14.000000000 +0200
@@ -1,3 +1,8 @@
+[test]
+mock
+PyYAML
+pytest
+
[yaml]
PyYAML
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ConfigArgParse-1.3/PKG-INFO
new/ConfigArgParse-1.5.1/PKG-INFO
--- old/ConfigArgParse-1.3/PKG-INFO 2021-02-15 00:17:36.000000000 +0100
+++ new/ConfigArgParse-1.5.1/PKG-INFO 2021-07-01 15:11:14.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ConfigArgParse
-Version: 1.3
+Version: 1.5.1
Summary: A drop-in replacement for argparse that allows options to also be set
via config files and/or environment variables.
Home-page: https://github.com/bw2/ConfigArgParse
License: MIT
@@ -95,7 +95,7 @@
.. code:: py
- # settings for my_script.py
+ # settings for config_test.py
genome = HCMV # cytomegalovirus genome
dbsnp = /data/dbsnp/variants.vcf
@@ -486,7 +486,9 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
+Provides-Extra: test
Provides-Extra: yaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ConfigArgParse-1.3/README.rst
new/ConfigArgParse-1.5.1/README.rst
--- old/ConfigArgParse-1.3/README.rst 2021-02-14 23:41:31.000000000 +0100
+++ new/ConfigArgParse-1.5.1/README.rst 2021-05-10 21:38:05.000000000 +0200
@@ -89,7 +89,7 @@
.. code:: py
- # settings for my_script.py
+ # settings for config_test.py
genome = HCMV # cytomegalovirus genome
dbsnp = /data/dbsnp/variants.vcf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ConfigArgParse-1.3/configargparse.py
new/ConfigArgParse-1.5.1/configargparse.py
--- old/ConfigArgParse-1.3/configargparse.py 2021-02-15 00:09:27.000000000
+0100
+++ new/ConfigArgParse-1.5.1/configargparse.py 2021-07-01 15:10:04.000000000
+0200
@@ -6,6 +6,7 @@
import sys
import types
from collections import OrderedDict
+import textwrap
if sys.version_info >= (3, 0):
from io import StringIO
@@ -82,8 +83,8 @@
stream: A config file input stream (such as an open file object).
Returns:
- OrderedDict of items where the keys have type string and the
- values have type either string or list (eg. to support config file
+ OrderedDict: Items where the keys are strings and the
+ values are either strings or lists (eg. to support config file
formats like YAML which allow lists).
"""
raise NotImplementedError("parse(..) not implemented")
@@ -94,8 +95,8 @@
Args:
items: an OrderedDict of items to be converted to the config file
- format. Keys should be strings, and values should be either strings
- or lists.
+ format. Keys should be strings, and values should be either
strings
+ or lists.
Returns:
Contents of config file as a string
@@ -109,7 +110,7 @@
class DefaultConfigFileParser(ConfigFileParser):
"""Based on a simplified subset of INI and YAML formats. Here is the
- supported syntax:
+ supported syntax::
# this is a comment
@@ -148,22 +149,19 @@
line = line.strip()
if not line or line[0] in ["#", ";", "["] or
line.startswith("---"):
continue
- white_space = "\\s*"
- key = r"(?P<key>[^:=;#\s]+?)"
- value = white_space+r"[:=\s]"+white_space+"(?P<value>.+?)"
- comment = white_space+"(?P<comment>\\s[;#].*)?"
-
- key_only_match = re.match("^" + key + comment + "$", line)
- if key_only_match:
- key = key_only_match.group("key")
- items[key] = "true"
- continue
-
- key_value_match = re.match("^"+key+value+comment+"$", line)
- if key_value_match:
- key = key_value_match.group("key")
- value = key_value_match.group("value")
+ match = re.match(r'^(?P<key>[^:=;#\s]+)\s*'
+
r'(?:(?P<equal>[:=\s])\s*([\'"]?)(?P<value>.+?)?\3)?'
+ r'\s*(?:\s[;#]\s*(?P<comment>.*?)\s*)?$', line)
+ if match:
+ key = match.group("key")
+ equal = match.group('equal')
+ value = match.group("value")
+ comment = match.group("comment")
+ if value is None and equal is not None and equal != ' ':
+ value = ''
+ elif value is None:
+ value = "true"
if value.startswith("[") and value.endswith("]"):
# handle special case of k=[1,2,3] or other json-like
syntax
try:
@@ -171,13 +169,12 @@
except Exception as e:
# for backward compatibility with legacy format (eg.
where config value is [a, b, c] instead of proper json ["a", "b", "c"]
value = [elem.strip() for elem in
value[1:-1].split(",")]
-
+ if comment:
+ comment = comment.strip()[1:].strip()
items[key] = value
- continue
-
-
- raise ConfigFileParserException("Unexpected line {} in {}:
{}".format(i,
- getattr(stream, 'name', 'stream'), line))
+ else:
+ raise ConfigFileParserException("Unexpected line {} in {}:
{}".format(i,
+ getattr(stream, 'name', 'stream'), line))
return items
def serialize(self, items):
@@ -230,6 +227,7 @@
config.read_string(stream.read())
except Exception as e:
raise ConfigFileParserException("Couldn't parse config file: %s" %
e)
+
# convert to dict and remove INI section names
result = OrderedDict()
for section in config.sections():
@@ -259,13 +257,14 @@
strict=True,
empty_lines_in_values=False,
)
- items = {"DEFAULT":items}
+ items = {"DEFAULT": items}
config.read_dict(items)
stream = io.StringIO()
config.write(stream)
stream.seek(0)
return stream.read()
+
class YAMLConfigFileParser(ConfigFileParser):
"""Parses YAML config files. Depends on the PyYAML module.
https://pypi.python.org/pypi/PyYAML
@@ -313,7 +312,6 @@
return result
-
def serialize(self, items, default_flow_style=False):
"""Does the inverse of config parsing by taking parsed values and
converting them back to a string representing config file contents.
@@ -344,10 +342,10 @@
def __init__(self, *args, **kwargs):
- """Supports args of the argparse.ArgumentParser constructor
- as **kwargs, as well as the following additional args.
+ r"""Supports args of the argparse.ArgumentParser constructor
+ as \*\*kwargs, as well as the following additional args.
- Additional Args:
+ Arguments:
add_config_file_help: Whether to add a description of config file
syntax to the help message.
add_env_var_help: Whether to add something to the help message for
@@ -363,12 +361,14 @@
taking precedence over previous ones. This allows an
application
to look for config files in multiple standard locations such as
the install directory, home directory, and current directory.
- Also, shell * syntax can be used to specify all conf files in a
- directory. For example:
- ["/etc/conf/app_config.ini",
- "/etc/conf/conf-enabled/*.ini",
- "~/.my_app_config.ini",
- "./app_config.txt"]
+ Also, shell \* syntax can be used to specify all conf files in
a
+ directory. For example::
+
+ ["/etc/conf/app_config.ini",
+ "/etc/conf/conf-enabled/*.ini",
+ "~/.my_app_config.ini",
+ "./app_config.txt"]
+
ignore_unknown_config_file_keys: If true, settings that are found
in a config file but don't correspond to any defined
configargparse args will be ignored. If false, they will be
@@ -451,29 +451,39 @@
"""Supports all the same args as the ArgumentParser.parse_args(..),
as well as the following additional args.
- Additional Args:
+ Arguments:
args: a list of args as in argparse, or a string (eg. "-x -y bla")
config_file_contents: String. Used for testing.
env_vars: Dictionary. Used for testing.
"""
- args, argv = self.parse_known_args(args = args,
- namespace = namespace,
- config_file_contents = config_file_contents,
- env_vars = env_vars)
+ args, argv = self.parse_known_args(
+ args=args,
+ namespace=namespace,
+ config_file_contents=config_file_contents,
+ env_vars=env_vars,
+ ignore_help_args=False)
+
if argv:
self.error('unrecognized arguments: %s' % ' '.join(argv))
return args
-
- def parse_known_args(self, args = None, namespace = None,
- config_file_contents = None, env_vars = os.environ):
+ def parse_known_args(
+ self,
+ args=None,
+ namespace=None,
+ config_file_contents=None,
+ env_vars=os.environ,
+ ignore_help_args=False,
+ ):
"""Supports all the same args as the ArgumentParser.parse_args(..),
as well as the following additional args.
- Additional Args:
+ Arguments:
args: a list of args as in argparse, or a string (eg. "-x -y bla")
- config_file_contents: String. Used for testing.
- env_vars: Dictionary. Used for testing.
+ config_file_contents (str). Used for testing.
+ env_vars (dict). Used for testing.
+ ignore_help_args (bool): This flag determines behavior when user
specifies --help or -h. If False,
+ it will have the default behavior - printing help and exiting.
If True, it won't do either.
"""
if args is None:
args = sys.argv[1:]
@@ -485,6 +495,9 @@
for a in self._actions:
a.is_positional_arg = not a.option_strings
+ if ignore_help_args:
+ args = [arg for arg in args if arg not in ("-h", "--help")]
+
# maps a string describing the source (eg. env var) to a settings dict
# to keep track of where values came from (used by print_values()).
# The settings dicts for env vars and config files will then map
@@ -628,6 +641,20 @@
self.write_config_file(namespace, output_file_paths, exit_after=True)
return namespace, unknown_args
+ def get_source_to_settings_dict(self):
+ """If called after parse_args() or parse_known_args(), this dict. will
contain up to 4 keys corresponding
+ to where a given option's value is coming from:
+ "command_line"
+ "environment_variables"
+ "config_file"
+ "defaults"
+ Each such key, will be mapped to another dictionary containing the
options set via that method. Here the key
+ will be the option name, and the value will be a 2-tuple of the form
(argparse Action obj, string value).
+ """
+
+ return self._source_to_settings
+
+
def write_config_file(self, parsed_namespace, output_file_paths,
exit_after=False):
"""Write the given settings to output files.
@@ -652,12 +679,10 @@
for output_file_path in output_file_paths:
with self._config_file_open_func(output_file_path, "w") as
output_file:
output_file.write(file_contents)
- message = "Wrote config file to " + ", ".join(output_file_paths)
- if exit_after:
- self.exit(0, message)
- else:
- print(message)
+ print("Wrote config file to " + ", ".join(output_file_paths))
+ if exit_after:
+ self.exit(0)
def get_command_line_key_for_unknown_config_file_setting(self, key):
"""Compute a commandline arg key to be used for a config file setting
@@ -681,7 +706,7 @@
source_to_settings: the dictionary described in parse_known_args()
parsed_namespace: namespace object created within
parse_known_args()
Returns:
- an OrderedDict where keys are strings and values are either strings
+ OrderedDict: where keys are strings and values are either strings
or lists
"""
config_file_items = OrderedDict()
@@ -745,6 +770,11 @@
elif value.lower() in ("false", "no", "0"):
# don't append when set to "false" / "no"
pass
+ elif isinstance(action, argparse._CountAction):
+ for arg in args:
+ if any([arg.startswith(s) for s in action.option_strings]):
+ value = 0
+ args += [action.option_strings[0]] * int(value)
else:
self.error("Unexpected value for %s: '%s'. Expecting 'true', "
"'false', 'yes', 'no', '1' or '0'" % (key, value))
@@ -795,7 +825,6 @@
return keys
-
def _open_config_files(self, command_line_args):
"""Tries to parse config file path(s) from within command_line_args.
Returns a list of opened config files, including files specified on the
@@ -854,6 +883,12 @@
errno, msg = e.args
else:
msg = str(e)
+ # close previously opened config files
+ for config_file in config_files:
+ try:
+ config_file.close()
+ except Exception:
+ pass
self.error("Unable to open config file: %s. Error: %s" % (
user_config_file, msg
))
@@ -946,10 +981,12 @@
msg += (" If an arg is specified in more than one place, then "
"commandline values override %s.") % (
" which override ".join(value_sources))
- if msg:
- self.description = (self.description or "") + " " + msg
- return argparse.ArgumentParser.format_help(self)
+ text_width = max(self._get_formatter()._width, 11)
+ msg = textwrap.fill(msg, text_width)
+
+ return (argparse.ArgumentParser.format_help(self)
+ + ("\n{}\n".format(msg) if msg != "" else ""))
def add_argument(self, *args, **kwargs):
@@ -957,7 +994,7 @@
This method supports the same args as ArgumentParser.add_argument(..)
as well as the additional args below.
- Additional Args:
+ Arguments:
env_var: If set, the value of this environment variable will override
any config file or default values for this arg (but can itself
be overridden on the commandline). Also, if auto_env_var_prefix is
@@ -1018,6 +1055,12 @@
else:
arg_names.append(arg_string)
+ """
+ return any(
+ arg_name.startswith(potential_arg) for potential_arg in
potential_command_line_args for arg_name in arg_names
+ )
+ # TODO: need to support allow_abbrev, exit_on.. new args etc.
+ """
return any(
potential_arg in arg_names for potential_arg in
potential_command_line_args
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ConfigArgParse-1.3/setup.py
new/ConfigArgParse-1.5.1/setup.py
--- old/ConfigArgParse-1.3/setup.py 2021-02-15 00:14:13.000000000 +0100
+++ new/ConfigArgParse-1.5.1/setup.py 2021-07-01 14:41:49.000000000 +0200
@@ -49,7 +49,10 @@
command = sys.argv[-1]
if command == 'publish':
- os.system('python setup.py sdist upload')
+ os.system('rm -rf dist')
+ os.system('python setup.py sdist')
+ os.system('python3 setup.py bdist_wheel')
+ os.system('twine upload dist/*whl dist/*gz')
sys.exit()
elif command == "coverage":
try:
@@ -70,13 +73,15 @@
install_requires = []
tests_require = [
+ 'mock',
'PyYAML',
+ 'pytest',
]
setup(
name='ConfigArgParse',
- version="1.3",
+ version="1.5.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,
@@ -99,6 +104,7 @@
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
],
@@ -108,5 +114,6 @@
tests_require=tests_require,
extras_require = {
'yaml': ["PyYAML"],
+ 'test': tests_require,
}
)
Binary files old/ConfigArgParse-1.3/tests/__init__.pyc and
new/ConfigArgParse-1.5.1/tests/__init__.pyc differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ConfigArgParse-1.3/tests/test_configargparse.py
new/ConfigArgParse-1.5.1/tests/test_configargparse.py
--- old/ConfigArgParse-1.3/tests/test_configargparse.py 2021-02-14
23:41:54.000000000 +0100
+++ new/ConfigArgParse-1.5.1/tests/test_configargparse.py 2021-07-01
15:04:28.000000000 +0200
@@ -19,6 +19,11 @@
else:
from StringIO import StringIO
+if sys.version_info >= (3, 10):
+ OPTIONAL_ARGS_STRING="options"
+else:
+ OPTIONAL_ARGS_STRING="optional arguments"
+
# set COLUMNS to get expected wrapping
os.environ['COLUMNS'] = '80'
@@ -35,7 +40,7 @@
def error_method(self, message):
raise argparse.ArgumentError(None, message)
- def exit_method(self, status, message):
+ def exit_method(self, status, message=None):
self._exit_method_called = True
arg_parser._exit_method_called = False
@@ -77,9 +82,9 @@
return self.parser
- def assertParseArgsRaises(self, regex, *args, **kwargs):
+ def assertParseArgsRaises(self, regex, args, **kwargs):
self.assertRaisesRegex(argparse.ArgumentError, regex, self.parse,
- *args, **kwargs)
+ args=args, **kwargs)
class TestBasicUseCases(TestCase):
@@ -249,25 +254,24 @@
if not use_groups:
self.assertRegex(self.format_help(),
'usage: .* \\[-h\\] --genome GENOME \\[-v\\] -g MY_CFG_FILE\n?'
- '\\s+\\[-d DBSNP\\]\\s+\\[-f FRMT\\]\\s+vcf \\[vcf ...\\]\n\n'
+
- 9*r'(.+\s+)'+ # repeated 8 times because .+ matches atmost 1
line
+ '\\s+\\[-d DBSNP\\]\\s+\\[-f FRMT\\]\\s+vcf \\[vcf ...\\]\n\n'
'positional arguments:\n'
' vcf \\s+ Variant file\\(s\\)\n\n'
- 'optional arguments:\n'
+ '%s:\n'
' -h, --help \\s+ show this help message and exit\n'
' --genome GENOME \\s+ Path to genome file\n'
' -v\n'
' -g MY_CFG_FILE, --my-cfg-file MY_CFG_FILE\n'
' -d DBSNP, --dbsnp DBSNP\\s+\\[env var: DBSNP_PATH\\]\n'
- ' -f FRMT, --format FRMT\\s+\\[env var: OUTPUT_FORMAT\\]\n')
+ ' -f FRMT, --format FRMT\\s+\\[env var:
OUTPUT_FORMAT\\]\n\n'%OPTIONAL_ARGS_STRING +
+ 7*r'(.+\s*)')
else:
self.assertRegex(self.format_help(),
'usage: .* \\[-h\\] --genome GENOME \\[-v\\] -g MY_CFG_FILE\n?'
- '\\s+\\[-d DBSNP\\]\\s+\\[-f FRMT\\]\\s+vcf \\[vcf ...\\]\n\n'+
- 9*r'.+\s+'+ # repeated 8 times because .+ matches atmost 1
line
+ '\\s+\\[-d DBSNP\\]\\s+\\[-f FRMT\\]\\s+vcf \\[vcf ...\\]\n\n'
'positional arguments:\n'
' vcf \\s+ Variant file\\(s\\)\n\n'
- 'optional arguments:\n'
+ '%s:\n'
' -h, --help \\s+ show this help message and exit\n\n'
'g1:\n'
' --genome GENOME \\s+ Path to genome file\n'
@@ -275,7 +279,8 @@
' -g MY_CFG_FILE, --my-cfg-file MY_CFG_FILE\n\n'
'g2:\n'
' -d DBSNP, --dbsnp DBSNP\\s+\\[env var: DBSNP_PATH\\]\n'
- ' -f FRMT, --format FRMT\\s+\\[env var: OUTPUT_FORMAT\\]\n')
+ ' -f FRMT, --format FRMT\\s+\\[env var:
OUTPUT_FORMAT\\]\n\n'%OPTIONAL_ARGS_STRING +
+ 7*r'(.+\s*)')
self.assertParseArgsRaises("invalid choice: 'ZZZ'",
args="--genome hg19 -g %s --format ZZZ f.vcf" % config_file2.name)
@@ -311,6 +316,16 @@
output = out.getvalue().strip()
self.assertEqual(output, expected_output)
+ def testIgnoreHelpArgs(self):
+ p = self.initParser()
+ self.add_arg('--arg1')
+ args, _ = self.parse_known('--arg2 --help', ignore_help_args=True)
+ self.assertEqual(args.arg1, None)
+ self.add_arg('--arg2')
+ args, _ = self.parse_known('--arg2 3 --help', ignore_help_args=True)
+ self.assertEqual(args.arg2, "3")
+ self.assertRaisesRegex(TypeError, "exit", self.parse_known, '--arg2 3
--help', ignore_help_args=False)
+
def testPositionalAndConfigVarLists(self):
self.initParser()
self.add_arg("a")
@@ -321,7 +336,6 @@
self.assertEqual(ns.arg, ['Shell', 'someword', 'anotherword'])
self.assertEqual(ns.a, "positional_value")
-
def testMutuallyExclusiveArgs(self):
config_file = tempfile.NamedTemporaryFile(mode="w", delete=True)
@@ -360,9 +374,8 @@
self.assertRegex(self.format_help(),
r'usage: .* \[-h\] --genome GENOME \[-v\]\s+ \(-f1 TYPE1_CFG_FILE
\|'
- ' \\s*-f2 TYPE2_CFG_FILE\\)\\s+\\(-f FRMT \\| -b\\)\n\n' +
- 7*r'.+\s+'+ # repeated 7 times because .+ matches atmost 1 line
- 'optional arguments:\n'
+ ' \\s*-f2 TYPE2_CFG_FILE\\)\\s+\\(-f FRMT \\| -b\\)\n\n'
+ '%s:\n'
' -h, --help show this help message and exit\n'
' -f1 TYPE1_CFG_FILE, --type1-cfg-file TYPE1_CFG_FILE\n'
' -f2 TYPE2_CFG_FILE, --type2-cfg-file TYPE2_CFG_FILE\n'
@@ -370,7 +383,8 @@
' -b, --bam\\s+\\[env var: BAM_FORMAT\\]\n\n'
'group1:\n'
' --genome GENOME Path to genome file\n'
- ' -v\n')
+ ' -v\n\n'%OPTIONAL_ARGS_STRING +
+ 5*r'(.+\s*)')
config_file.close()
def testSubParsers(self):
@@ -486,6 +500,7 @@
self.assertParseArgsRaises("argument -x is required"
if sys.version_info.major < 3 else
"the following arguments are required: -x,
--y",
+ args="",
config_file_contents="-x 3")
self.assertParseArgsRaises("invalid float value: 'abc'",
args="-x 5",
@@ -511,6 +526,46 @@
env_vars={"bla": "2"})
self.assertEqual(set(args), {"--bla=3", "-x", "1"})
+
+ def testQuotedArgumentValues(self):
+ self.initParser()
+ self.add_arg("-a")
+ self.add_arg("--b")
+ self.add_arg("-c")
+ self.add_arg("--d")
+ self.add_arg("-e")
+ self.add_arg("-q")
+ self.add_arg("--quotes")
+
+ # sys.argv equivalent of -a="1" --b "1" -c= --d "" -e=: -q "\"'"
--quotes "\"'"
+ ns = self.parse(args=['-a=1', '--b', '1', '-c=', '--d', '', '-e=:',
+ '-q', '"\'', '--quotes', '"\''],
+ env_vars={}, config_file_contents="")
+
+ self.assertEqual(ns.a, "1")
+ self.assertEqual(ns.b, "1")
+ self.assertEqual(ns.c, "")
+ self.assertEqual(ns.d, "")
+ self.assertEqual(ns.e, ":")
+ self.assertEqual(ns.q, '"\'')
+ self.assertEqual(ns.quotes, '"\'')
+
+ def testQuotedConfigFileValues(self):
+ self.initParser()
+ self.add_arg("--a")
+ self.add_arg("--b")
+ self.add_arg("--c")
+
+ ns = self.parse(args="", env_vars={}, config_file_contents="""
+ a="1"
+ b=:
+ c=
+ """)
+
+ self.assertEqual(ns.a, "1")
+ self.assertEqual(ns.b, ":")
+ self.assertEqual(ns.c, "")
+
def testBooleanValuesCanBeExpressedAsNumbers(self):
self.initParser()
store_true_env_var_name = "STORE_TRUE"
@@ -563,6 +618,7 @@
self.add_arg("-v", "--verbose", env_var="VERBOSE", action="store_true")
self.assertParseArgsRaises("Unexpected value for VERBOSE: 'bla'. "
"Expecting 'true', 'false', 'yes', 'no',
'1' or '0'",
+ args="",
env_vars={"VERBOSE" : "bla"})
ns = self.parse("",
config_file_contents="verbose=true",
@@ -703,6 +759,28 @@
self.assertEqual(ns.arg, ['Shell', 'someword', 'anotherword'])
self.assertEqual(ns.a, "positional_value")
+ def testCounterCommandLine(self):
+ self.initParser()
+ self.add_arg("--verbose", "-v", action="count", default=0)
+
+ ns = self.parse(args="-v -v -v", env_vars={})
+ self.assertEqual(ns.verbose, 3)
+
+ ns = self.parse(args="-vvv", env_vars={})
+ self.assertEqual(ns.verbose, 3)
+
+ def testCounterConfigFile(self):
+ self.initParser()
+ self.add_arg("--verbose", "-v", action="count", default=0)
+
+ ns = self.parse(args="", env_vars={}, config_file_contents="""
+ verbose""")
+ self.assertEqual(ns.verbose, 1)
+
+ ns = self.parse(args="", env_vars={}, config_file_contents="""
+ verbose=3""")
+ self.assertEqual(ns.verbose, 3)
+
class TestMisc(TestCase):
# TODO test different action types with config file, env var
@@ -770,7 +848,8 @@
self.add_arg('--genome', help='Path to genome file', required=True)
self.assertParseArgsRaises("argument -c/--config is required"
if sys.version_info.major < 3 else
- "arguments are required: -c/--config",)
+ "arguments are required: -c/--config",
+ args="")
temp_cfg2 = tempfile.NamedTemporaryFile(mode="w", delete=True)
ns = self.parse("-c " + temp_cfg2.name)
@@ -783,15 +862,17 @@
self.assertEqual(ns.genome, "hg20")
self.assertRegex(self.format_help(),
- 'usage: .* \\[-h\\] -c CONFIG_FILE --genome GENOME\n\n'+
- 7*r'.+\s+'+ # repeated 7 times because .+ matches atmost 1 line
- 'optional arguments:\n'
+ 'usage: .* \\[-h\\] -c CONFIG_FILE --genome GENOME\n\n'
+ '%s:\n'
' -h, --help\\s+ show this help message and exit\n'
' -c CONFIG_FILE, --config CONFIG_FILE\\s+ my config file\n'
- ' --genome GENOME\\s+ Path to genome file\n')
+ ' --genome GENOME\\s+ Path to genome
file\n\n'%OPTIONAL_ARGS_STRING +
+ 5*r'(.+\s*)')
# just run print_values() to make sure it completes and returns None
- self.assertIsNone(self.parser.print_values(file=sys.stderr))
+ output = StringIO()
+ self.assertIsNone(self.parser.print_values(file=output))
+ self.assertIn("Command Line Args:", output.getvalue())
# test ignore_unknown_config_file_keys=False
self.initParser(ignore_unknown_config_file_keys=False)
@@ -842,21 +923,21 @@
self.assertRegex(self.format_help(),
r'usage: .* \[-h\] -c CONFIG_FILE\s+'
r'\[-w CONFIG_OUTPUT_PATH\]\s* --arg1\s+ARG1\s*\[--flag\]\s*'
- 'Args that start with \'--\' \\(eg. --arg1\\) can also be set in a
'
- r'config file\s*\(~/.myconfig or specified via -c\).\s*'
- r'Config file syntax allows: key=value,\s*flag=true,
stuff=\[a,b,c\] '
- r'\(for details, see syntax at https://goo.gl/R74nmi\).\s*'
- r'If an arg is specified in more than\s*one place, then '
- r'commandline values\s*override config file values which
override\s*'
- r'defaults.\s*'
- r'optional arguments:\s*'
+ '%s:\\s*'
'-h, --help \\s* show this help message and exit\n\\s*'
r'-c CONFIG_FILE, --config CONFIG_FILE\s+my config file\s*'
r'-w CONFIG_OUTPUT_PATH, --write-config
CONFIG_OUTPUT_PATH\s*takes\s*'
r'the current command line args and writes them\s*'
r'out to a config file at the given path, then exits\s*'
r'--arg1 ARG1\s*Arg1 help text\s*'
- r'--flag \s*Flag help text'
+ r'--flag \s*Flag help text\s*'
+ 'Args that start with \'--\' \\(eg. --arg1\\) can also be set in a
'
+ r'config file\s*\(~/.myconfig or specified via -c\).\s*'
+ r'Config file syntax allows: key=value,\s*flag=true,
stuff=\[a,b,c\] '
+ r'\(for details, see syntax at https://goo.gl/R74nmi\).\s*'
+ r'If an arg is specified in more than\s*one place, then '
+ r'commandline values\s*override config file values which
override\s*'
+ r'defaults.'%OPTIONAL_ARGS_STRING
)
def test_FormatHelpProg(self):
@@ -918,6 +999,7 @@
expected_config_file_contents.strip())
self.assertRaisesRegex(ValueError, "Couldn't open / for writing:",
self.parse, args = command_line_args + " -w /")
+ cfg_f.close()
def testConstructor_WriteOutConfigFileArgs2(self):
# Test constructor args:
@@ -962,6 +1044,7 @@
expected_config_file_contents.strip())
self.assertRaisesRegex(ValueError, "Couldn't open / for writing:",
self.parse, args = command_line_args + " -w /")
+ cfg_f.close()
def testConstructor_WriteOutConfigFileArgsLong(self):
"""Test config writing with long version of arg
@@ -1005,6 +1088,7 @@
expected_config_file_contents.strip())
self.assertRaisesRegex(ValueError, "Couldn't open / for writing:",
self.parse, args = command_line_args + " --write-config /")
+ cfg_f.close()
def testMethodAliases(self):
p = self.parser
@@ -1102,6 +1186,249 @@
self.assertListEqual(parsed_obj['_list_arg1'], ['a', 'b', 'c'])
self.assertListEqual(parsed_obj['_list_arg2'], [1, 2, 3])
+ def testDefaultConfigFileParser_BasicValues(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key = value # comment # comment', 'expected': ('key',
'value', 'comment # comment')},
+ {'line': 'key=value#comment ', 'expected': ('key',
'value#comment', None)},
+ {'line': 'key=value', 'expected': ('key',
'value', None)},
+ {'line': 'key =value', 'expected': ('key',
'value', None)},
+ {'line': 'key= value', 'expected': ('key',
'value', None)},
+ {'line': 'key = value', 'expected': ('key',
'value', None)},
+ {'line': 'key = value', 'expected': ('key',
'value', None)},
+ {'line': ' key = value ', 'expected': ('key',
'value', None)},
+ {'line': 'key:value', 'expected': ('key',
'value', None)},
+ {'line': 'key :value', 'expected': ('key',
'value', None)},
+ {'line': 'key: value', 'expected': ('key',
'value', None)},
+ {'line': 'key : value', 'expected': ('key',
'value', None)},
+ {'line': 'key : value', 'expected': ('key',
'value', None)},
+ {'line': ' key : value ', 'expected': ('key',
'value', None)},
+ {'line': 'key value', 'expected': ('key',
'value', None)},
+ {'line': 'key value', 'expected': ('key',
'value', None)},
+ {'line': ' key value ', 'expected': ('key',
'value', None)},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
+ def testDefaultConfigFileParser_QuotedValues(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key="value"', 'expected': ('key',
'value', None)},
+ {'line': 'key = "value"', 'expected': ('key',
'value', None)},
+ {'line': ' key = "value" ', 'expected': ('key',
'value', None)},
+ {'line': 'key=" value "', 'expected': ('key',
' value ', None)},
+ {'line': 'key = " value "', 'expected': ('key',
' value ', None)},
+ {'line': ' key = " value " ', 'expected': ('key',
' value ', None)},
+ {'line': "key='value'", 'expected': ('key',
'value', None)},
+ {'line': "key = 'value'", 'expected': ('key',
'value', None)},
+ {'line': " key = 'value' ", 'expected': ('key',
'value', None)},
+ {'line': "key=' value '", 'expected': ('key',
' value ', None)},
+ {'line': "key = ' value '", 'expected': ('key',
' value ', None)},
+ {'line': " key = ' value ' ", 'expected': ('key',
' value ', None)},
+ {'line': 'key="', 'expected': ('key',
'"', None)},
+ {'line': 'key = "', 'expected': ('key',
'"', None)},
+ {'line': ' key = " ', 'expected': ('key',
'"', None)},
+ {'line': 'key = \'"value"\'', 'expected': ('key',
'"value"', None)},
+ {'line': 'key = "\'value\'"', 'expected': ('key',
"'value'", None)},
+ {'line': 'key = ""value""', 'expected': ('key',
'"value"', None)},
+ {'line': 'key = \'\'value\'\'', 'expected': ('key',
"'value'", None)},
+ {'line': 'key="value', 'expected': ('key',
'"value', None)},
+ {'line': 'key = "value', 'expected': ('key',
'"value', None)},
+ {'line': ' key = "value ', 'expected': ('key',
'"value', None)},
+ {'line': 'key=value"', 'expected': ('key',
'value"', None)},
+ {'line': 'key = value"', 'expected': ('key',
'value"', None)},
+ {'line': ' key = value " ', 'expected': ('key',
'value "', None)},
+ {'line': "key='value", 'expected': ('key',
"'value", None)},
+ {'line': "key = 'value", 'expected': ('key',
"'value", None)},
+ {'line': " key = 'value ", 'expected': ('key',
"'value", None)},
+ {'line': "key=value'", 'expected': ('key',
"value'", None)},
+ {'line': "key = value'", 'expected': ('key',
"value'", None)},
+ {'line': " key = value ' ", 'expected': ('key',
"value '", None)},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
+ def testDefaultConfigFileParser_BlankValues(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key=', 'expected': ('key',
'', None)},
+ {'line': 'key =', 'expected': ('key',
'', None)},
+ {'line': 'key= ', 'expected': ('key',
'', None)},
+ {'line': 'key = ', 'expected': ('key',
'', None)},
+ {'line': 'key = ', 'expected': ('key',
'', None)},
+ {'line': ' key = ', 'expected': ('key',
'', None)},
+ {'line': 'key:', 'expected': ('key',
'', None)},
+ {'line': 'key :', 'expected': ('key',
'', None)},
+ {'line': 'key: ', 'expected': ('key',
'', None)},
+ {'line': 'key : ', 'expected': ('key',
'', None)},
+ {'line': 'key : ', 'expected': ('key',
'', None)},
+ {'line': ' key : ', 'expected': ('key',
'', None)},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
+ def testDefaultConfigFileParser_UnspecifiedValues(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key ', 'expected': ('key',
'true', None)},
+ {'line': 'key', 'expected': ('key',
'true', None)},
+ {'line': 'key ', 'expected': ('key',
'true', None)},
+ {'line': ' key ', 'expected': ('key',
'true', None)},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
+ def testDefaultConfigFileParser_ColonEqualSignValue(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key=:', 'expected': ('key',
':', None)},
+ {'line': 'key =:', 'expected': ('key',
':', None)},
+ {'line': 'key= :', 'expected': ('key',
':', None)},
+ {'line': 'key = :', 'expected': ('key',
':', None)},
+ {'line': 'key = :', 'expected': ('key',
':', None)},
+ {'line': ' key = : ', 'expected': ('key',
':', None)},
+ {'line': 'key:=', 'expected': ('key',
'=', None)},
+ {'line': 'key :=', 'expected': ('key',
'=', None)},
+ {'line': 'key: =', 'expected': ('key',
'=', None)},
+ {'line': 'key : =', 'expected': ('key',
'=', None)},
+ {'line': 'key : =', 'expected': ('key',
'=', None)},
+ {'line': ' key : = ', 'expected': ('key',
'=', None)},
+ {'line': 'key==', 'expected': ('key',
'=', None)},
+ {'line': 'key ==', 'expected': ('key',
'=', None)},
+ {'line': 'key= =', 'expected': ('key',
'=', None)},
+ {'line': 'key = =', 'expected': ('key',
'=', None)},
+ {'line': 'key = =', 'expected': ('key',
'=', None)},
+ {'line': ' key = = ', 'expected': ('key',
'=', None)},
+ {'line': 'key::', 'expected': ('key',
':', None)},
+ {'line': 'key ::', 'expected': ('key',
':', None)},
+ {'line': 'key: :', 'expected': ('key',
':', None)},
+ {'line': 'key : :', 'expected': ('key',
':', None)},
+ {'line': 'key : :', 'expected': ('key',
':', None)},
+ {'line': ' key : : ', 'expected': ('key',
':', None)},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
+ def testDefaultConfigFileParser_ValuesWithComments(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key=value#comment ', 'expected': ('key',
'value#comment', None)},
+ {'line': 'key=value #comment', 'expected': ('key',
'value', 'comment')},
+ {'line': ' key = value # comment', 'expected': ('key',
'value', 'comment')},
+ {'line': 'key:value#comment', 'expected': ('key',
'value#comment', None)},
+ {'line': 'key:value #comment', 'expected': ('key',
'value', 'comment')},
+ {'line': ' key : value # comment', 'expected': ('key',
'value', 'comment')},
+ {'line': 'key=value;comment ', 'expected': ('key',
'value;comment', None)},
+ {'line': 'key=value ;comment', 'expected': ('key',
'value', 'comment')},
+ {'line': ' key = value ; comment', 'expected': ('key',
'value', 'comment')},
+ {'line': 'key:value;comment', 'expected': ('key',
'value;comment', None)},
+ {'line': 'key:value ;comment', 'expected': ('key',
'value', 'comment')},
+ {'line': ' key : value ; comment', 'expected': ('key',
'value', 'comment')},
+ {'line': 'key = value # comment # comment', 'expected': ('key',
'value', 'comment # comment')},
+ {'line': 'key = "value # comment" # comment', 'expected': ('key',
'value # comment', 'comment')},
+ {'line': 'key = "#" ; comment', 'expected': ('key',
'#', 'comment')},
+ {'line': 'key = ";" # comment', 'expected': ('key',
';', 'comment')},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
+ def testDefaultConfigFileParser_NegativeValues(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key = -10', 'expected': ('key',
'-10', None)},
+ {'line': 'key : -10', 'expected': ('key',
'-10', None)},
+ {'line': 'key -10', 'expected': ('key',
'-10', None)},
+ {'line': 'key = "-10"', 'expected': ('key',
'-10', None)},
+ {'line': "key = '-10'", 'expected': ('key',
'-10', None)},
+ {'line': 'key=-10', 'expected': ('key',
'-10', None)},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
+ def testDefaultConfigFileParser_KeySyntax(self):
+ p = configargparse.DefaultConfigFileParser()
+
+ # test the all syntax case
+ config_lines = [
+ {'line': 'key_underscore = value', 'expected':
('key_underscore', 'value', None)},
+ {'line': 'key_underscore=', 'expected':
('key_underscore', '', None)},
+ {'line': 'key_underscore', 'expected':
('key_underscore', 'true', None)},
+ {'line': '_key_underscore = value', 'expected':
('_key_underscore', 'value', None)},
+ {'line': '_key_underscore=', 'expected':
('_key_underscore', '', None)},
+ {'line': '_key_underscore', 'expected':
('_key_underscore', 'true', None)},
+ {'line': 'key_underscore_ = value', 'expected':
('key_underscore_', 'value', None)},
+ {'line': 'key_underscore_=', 'expected':
('key_underscore_', '', None)},
+ {'line': 'key_underscore_', 'expected':
('key_underscore_', 'true', None)},
+ {'line': 'key-dash = value', 'expected':
('key-dash', 'value', None)},
+ {'line': 'key-dash=', 'expected':
('key-dash', '', None)},
+ {'line': 'key-dash', 'expected':
('key-dash', 'true', None)},
+ {'line': 'key@word = value', 'expected':
('key@word', 'value', None)},
+ {'line': 'key@word=', 'expected':
('key@word', '', None)},
+ {'line': 'key@word', 'expected':
('key@word', 'true', None)},
+ {'line': 'key$word = value', 'expected':
('key$word', 'value', None)},
+ {'line': 'key$word=', 'expected':
('key$word', '', None)},
+ {'line': 'key$word', 'expected':
('key$word', 'true', None)},
+ {'line': 'key.word = value', 'expected':
('key.word', 'value', None)},
+ {'line': 'key.word=', 'expected':
('key.word', '', None)},
+ {'line': 'key.word', 'expected':
('key.word', 'true', None)},
+ ]
+
+ for test in config_lines:
+ parsed_obj = p.parse(StringIO(test['line']))
+ parsed_obj = dict(parsed_obj)
+ expected = {test['expected'][0]: test['expected'][1]}
+ self.assertDictEqual(parsed_obj, expected,
+ msg="Line %r" % (test['line']))
+
def testYAMLConfigFileParser_Basic(self):
try:
import yaml
@@ -1171,7 +1498,14 @@
else:
test_argparse_source_code = inspect.getsource(test.test_argparse)
test_argparse_source_code = test_argparse_source_code.replace(
- 'argparse.ArgumentParser', 'configargparse.ArgumentParser')
+ 'argparse.ArgumentParser', 'configargparse.ArgumentParser').replace(
+ 'TestHelpFormattingMetaclass', '_TestHelpFormattingMetaclass').replace(
+ 'test_main', '_test_main')
+
+ # pytest tries to collect tests from TestHelpFormattingMetaclass, and
+ # test_main, and raises a warning when it finds it's not a test class
+ # nor test function. Renaming TestHelpFormattingMetaclass and test_main
+ # prevents pytest from trying.
# run or debug a subset of the argparse tests
#test_argparse_source_code = test_argparse_source_code.replace(
Binary files old/ConfigArgParse-1.3/tests/test_configargparse.pyc and
new/ConfigArgParse-1.5.1/tests/test_configargparse.pyc differ