Skip to content

Commit

Permalink
Merge pull request #79 from ziadsawalha/config
Browse files Browse the repository at this point in the history
Config Fixes: `strict` parsing and deprecation warning
  • Loading branch information
stavxyz committed Aug 27, 2015
2 parents e81dd48 + 1955d61 commit 5519d3b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
46 changes: 29 additions & 17 deletions simpl/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,7 @@ def add_argument(self, parser, permissive=False, **override_kwargs):
kwargs['help'] = "%s (or set %s)" % (kwargs['help'],
kwargs['env'])
if permissive:
try:
required = kwargs.pop('required', None)
except KeyError:
pass
required = kwargs.pop('required', None)
try:
del kwargs['env']
except KeyError:
Expand Down Expand Up @@ -407,7 +404,8 @@ def _metaconfigure(self, argv=None):
options=self._metaconf._options, permissive=False, **override)
self._parser_kwargs.setdefault('parents', [])
self._parser_kwargs['parents'].append(metaparser)
self._metaconf.parse(argv=argv)
self._metaconf._values = self._metaconf.load_options(
argv=argv, permissive=True)
self._metaconf.provision(self)

@staticmethod
Expand Down Expand Up @@ -489,8 +487,8 @@ def parse_cli(self, argv=None, permissive=False):
valid, pass_thru = self.parse_passthru_args(argv[1:])
parsed, extras = parser.parse_known_args(valid)
if extras and not permissive:
raise AttributeError("Unrecognized arguments: %s" %
' ,'.join(extras))
self.build_parser(options, permissive=permissive)
parser.parse_args(argv[1:])
self.pass_thru_args = pass_thru + extras
else:
# maybe reset pass_thru_args on subsequent calls
Expand Down Expand Up @@ -542,7 +540,13 @@ def parse_ini(self, paths=None, namespace=None, permissive=False):
"""
namespace = namespace or self.prog
results = {}
self.ini_config = configparser.SafeConfigParser()
# DeprecationWarning: SafeConfigParser has been renamed to ConfigParser
# in Python 3.2. This alias will be removed in future versions. Use
# ConfigParser directly instead.
if sys.version_info < (3, 2):
self.ini_config = configparser.SafeConfigParser()
else:
self.ini_config = configparser.ConfigParser()

parser_errors = (configparser.NoOptionError,
configparser.NoSectionError)
Expand Down Expand Up @@ -603,10 +607,10 @@ def parse_keyring(self, namespace=None):
results[option.dest] = option.type(secret)
return results

def load_options(self, argv=None, keyring_namespace=None):
def load_options(self, argv=None, keyring_namespace=None, permissive=True):
"""Find settings from all sources."""
defaults = self.get_defaults()
args = self.parse_cli(argv=argv, permissive=True)
args = self.parse_cli(argv=argv, permissive=permissive)
env = self.parse_env()
secrets = self.parse_keyring(keyring_namespace)
ini = self.parse_ini()
Expand All @@ -618,10 +622,16 @@ def load_options(self, argv=None, keyring_namespace=None):
results.update(args)
return results

def parse(self, argv=None, keyring_namespace=None):
"""Find settings from all sources."""
def parse(self, argv=None, keyring_namespace=None, strict=False):
"""Find settings from all sources.
:returns: dict of parsed option name and values
:raises: SystemExit if invalid arguments supplied along with stdout
message (same as argparser).
"""
results = self.load_options(argv=argv,
keyring_namespace=keyring_namespace)
keyring_namespace=keyring_namespace,
permissive=not strict)
# Run validation
raise_for_group = {}
for option in self._options:
Expand Down Expand Up @@ -815,17 +825,19 @@ def parse_key_format(value):
SINGLETON = None


def init(options=None, ini_paths=None, argv=None):
def init(options=None, ini_paths=None, argv=None, strict=False):
"""Initialize singleton config and read/parse configuration.
:keyword bool strict: when true, will error out on invalid arguments
(default behavior is to ignore them)
:returns: the loaded configuration.
"""
global SINGLETON
SINGLETON = Config(
options=options,
ini_paths=ini_paths,
argv=argv)
SINGLETON.parse(argv)
SINGLETON.parse(argv, strict=strict)
return SINGLETON


Expand Down Expand Up @@ -855,7 +867,7 @@ def current():
return SINGLETON


def main():
def main(): # pragma: no cover
"""Simple tests."""
opts = [
Option('--foo'),
Expand All @@ -876,5 +888,5 @@ def main():
myconf.parse()
print(myconf)

if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
main()
9 changes: 8 additions & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import copy
import errno
import os
import string
import sys
import tempfile
import textwrap
Expand All @@ -35,6 +34,7 @@


class TestParsers(unittest.TestCase):

def test_comma_separated_strings(self):
expected = ['1', '2', '3']
result = config.comma_separated_strings("1,2,3")
Expand Down Expand Up @@ -88,6 +88,13 @@ def test_items(self):
self.assertEqual(cfg['one'], 1)
self.assertIsNone(cfg['none'])

def test_strict(self):
cfg = config.Config(options=[
config.Option('--one', default=1),
])
with self.assertRaises(SystemExit):
cfg.parse(['prog', '--foo'], strict=True)

@mock.patch.dict('os.environ', {'TEST_TWO': '2'})
def test_required(self):
self.assertEqual(os.environ['TEST_TWO'], '2')
Expand Down

0 comments on commit 5519d3b

Please sign in to comment.