Hello community,

here is the log from the commit of package python-knack for openSUSE:Factory 
checked in at 2019-05-22 11:16:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-knack (Old)
 and      /work/SRC/openSUSE:Factory/.python-knack.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-knack"

Wed May 22 11:16:33 2019 rev:7 rq:704423 version:0.6.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-knack/python-knack.changes        
2019-05-06 13:25:09.841020349 +0200
+++ /work/SRC/openSUSE:Factory/.python-knack.new.5148/python-knack.changes      
2019-05-22 11:16:43.162502081 +0200
@@ -1,0 +2,8 @@
+Tue May 21 09:51:57 UTC 2019 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 0.6.1:
+  * Always read from local for configured_default
+- from version 0.6.0
+  * Support local context chained config file
+
+-------------------------------------------------------------------

Old:
----
  v0.5.4.tar.gz

New:
----
  v0.6.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-knack.spec ++++++
--- /var/tmp/diff_new_pack.Rn3gtL/_old  2019-05-22 11:16:45.266500609 +0200
+++ /var/tmp/diff_new_pack.Rn3gtL/_new  2019-05-22 11:16:45.270500606 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-knack
-Version:        0.5.4
+Version:        0.6.1
 Release:        0
 Summary:        A Command-Line Interface framework
 License:        MIT

++++++ v0.5.4.tar.gz -> v0.6.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knack-0.5.4/knack/commands.py 
new/knack-0.6.1/knack/commands.py
--- old/knack-0.5.4/knack/commands.py   2019-03-29 20:11:28.000000000 +0100
+++ new/knack-0.6.1/knack/commands.py   2019-04-26 02:11:43.000000000 +0200
@@ -78,7 +78,10 @@
             return
 
         defaults_section = self.cli_ctx.config.defaults_section_name
+        use_local_config_original = self.cli_ctx.config.use_local_config
+        self.cli_ctx.config.set_to_use_local_config(True)
         config_value = self.cli_ctx.config.get(defaults_section, default_key, 
None)
+        self.cli_ctx.config.set_to_use_local_config(use_local_config_original)
         if config_value:
             logger.info("Configured default '%s' for arg %s", config_value, 
arg.name)
             overrides.settings['default'] = DefaultStr(config_value)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knack-0.5.4/knack/config.py 
new/knack-0.6.1/knack/config.py
--- old/knack-0.5.4/knack/config.py     2019-03-29 20:11:28.000000000 +0100
+++ new/knack-0.6.1/knack/config.py     2019-04-26 02:11:43.000000000 +0200
@@ -25,7 +25,7 @@
     _DEFAULT_CONFIG_FILE_NAME = 'config'
     _CONFIG_DEFAULTS_SECTION = 'defaults'
 
-    def __init__(self, config_dir=None, config_env_var_prefix=None, 
config_file_name=None):
+    def __init__(self, config_dir=None, config_env_var_prefix=None, 
config_file_name=None, use_local_config=None):
         """ Manages configuration options available in the CLI
 
         :param config_dir: The directory to store config files
@@ -38,7 +38,6 @@
         config_dir = config_dir or CLIConfig._DEFAULT_CONFIG_DIR
         ensure_dir(config_dir)
         config_env_var_prefix = config_env_var_prefix or 
CLIConfig._DEFAULT_CONFIG_ENV_VAR_PREFIX
-        self.config_parser = get_config_parser()
         env_var_prefix = '{}_'.format(config_env_var_prefix.upper())
         default_config_dir = os.path.expanduser(config_dir)
         self.config_dir = 
os.environ.get('{}CONFIG_DIR'.format(env_var_prefix), default_config_dir)
@@ -46,7 +45,24 @@
         self.config_path = os.path.join(self.config_dir, 
configuration_file_name)
         self._env_var_format = '{}{}'.format(env_var_prefix, 
'{section}_{option}')
         self.defaults_section_name = CLIConfig._CONFIG_DEFAULTS_SECTION
-        self.config_parser.read(self.config_path)
+        self.use_local_config = use_local_config
+        self._config_file_chain = []
+        current_dir = os.getcwd()
+        config_dir_name = os.path.basename(self.config_dir)
+        while current_dir:
+            current_config_dir = os.path.join(current_dir, config_dir_name)
+            # Stop if already in the default .azure
+            if (os.path.normcase(os.path.normpath(current_config_dir)) ==
+                    os.path.normcase(os.path.normpath(self.config_dir))):
+                break
+            if os.path.isdir(current_config_dir):
+                self._config_file_chain.append(_ConfigFile(current_config_dir,
+                                                           
os.path.join(current_config_dir, configuration_file_name)))
+            # Stop if already in root drive
+            if current_dir == os.path.dirname(current_dir):
+                break
+            current_dir = os.path.dirname(current_dir)
+        self._config_file_chain.append(_ConfigFile(self.config_dir, 
self.config_path))
 
     def env_var_name(self, section, option):
         return self._env_var_format.format(section=section.upper(),
@@ -55,16 +71,38 @@
     def has_option(self, section, option):
         if self.env_var_name(section, option) in os.environ:
             return True
-        return self.config_parser.has_option(section, option)
+        config_files = self._config_file_chain if self.use_local_config else 
self._config_file_chain[-1:]
+        return bool(next((f for f in config_files if f.has_option(section, 
option)), False))
 
     def get(self, section, option, fallback=_UNSET):
-        try:
-            env = self.env_var_name(section, option)
-            return os.environ[env] if env in os.environ else 
self.config_parser.get(section, option)
-        except (configparser.NoSectionError, configparser.NoOptionError):
-            if fallback is _UNSET:
-                raise
-            return fallback
+        env = self.env_var_name(section, option)
+        if env in os.environ:
+            return os.environ[env]
+        last_ex = None
+        for config in self._config_file_chain if self.use_local_config else 
self._config_file_chain[-1:]:
+            try:
+                return config.get(section, option)
+            except (configparser.NoSectionError, configparser.NoOptionError) 
as ex:
+                last_ex = ex
+
+        if fallback is _UNSET:
+            raise last_ex  # pylint:disable=raising-bad-type
+        return fallback
+
+    def items(self, section):
+        import re
+        pattern = self.env_var_name(section, '.+')
+        candidates = [(k.split('_')[-1], os.environ[k], k) for k in 
os.environ.keys() if re.match(pattern, k)]
+        result = {c[0]: c for c in candidates}
+        for config in self._config_file_chain if self.use_local_config else 
self._config_file_chain[-1:]:
+            try:
+                entries = config.items(section)
+                for name, value in entries:
+                    if name not in result:
+                        result[name] = (name, value, config.config_path)
+            except (configparser.NoSectionError, configparser.NoOptionError):
+                pass
+        return [{'name': name, 'value': value, 'source': source} for name, 
value, source in result.values()]
 
     def getint(self, section, option, fallback=_UNSET):
         return int(self.get(section, option, fallback))
@@ -78,6 +116,57 @@
             raise ValueError('Not a boolean: {}'.format(val))
         return CLIConfig._BOOLEAN_STATES[val.lower()]
 
+    def set_value(self, section, option, value):
+        if self.use_local_config:
+            current_config_dir = os.path.join(os.getcwd(), 
os.path.basename(self.config_dir))
+            config_file_path = os.path.join(current_config_dir, 
os.path.basename(self.config_path))
+            if config_file_path == self._config_file_chain[0].config_path:
+                self._config_file_chain[0].set_value(section, option, value)
+            else:
+                config = _ConfigFile(current_config_dir, config_file_path)
+                config.set_value(section, option, value)
+                self._config_file_chain.insert(0, config)
+        else:
+            self._config_file_chain[-1].set_value(section, option, value)
+
+    def set_to_use_local_config(self, use_local_config):
+        self.use_local_config = use_local_config
+
+
+class _ConfigFile(object):
+    _BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
+                       '0': False, 'no': False, 'false': False, 'off': False}
+
+    def __init__(self, config_dir, config_path):
+        self.config_dir = config_dir
+        self.config_path = config_path
+        self.config_parser = get_config_parser()
+        if os.path.exists(config_path):
+            self.config_parser.read(config_path)
+
+    def items(self, section):
+        return self.config_parser.items(section) if self.config_parser else []
+
+    def has_option(self, section, option):
+        return self.config_parser.has_option(section, option) if 
self.config_parser else False
+
+    def get(self, section, option):
+        if self.config_parser:
+            return self.config_parser.get(section, option)
+        raise configparser.NoOptionError(section, option)
+
+    def getint(self, section, option):
+        return int(self.get(section, option))
+
+    def getfloat(self, section, option):
+        return float(self.get(section, option))
+
+    def getboolean(self, section, option):
+        val = str(self.get(section, option))
+        if val.lower() not in _ConfigFile._BOOLEAN_STATES:
+            raise ValueError('Not a boolean: {}'.format(val))
+        return _ConfigFile._BOOLEAN_STATES[val.lower()]
+
     def set(self, config):
         ensure_dir(self.config_dir)
         with open(self.config_path, 'w') as configfile:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knack-0.5.4/knack/log.py new/knack-0.6.1/knack/log.py
--- old/knack-0.5.4/knack/log.py        2019-03-29 20:11:28.000000000 +0100
+++ new/knack-0.6.1/knack/log.py        2019-04-26 02:11:43.000000000 +0200
@@ -45,8 +45,8 @@
                 return wrap_msg_with_color
 
             cls.COLOR_MAP = {
-                logging.CRITICAL: _color_wrapper(colorama.Fore.RED),
-                logging.ERROR: _color_wrapper(colorama.Fore.RED),
+                logging.CRITICAL: _color_wrapper(colorama.Fore.LIGHTRED_EX),
+                logging.ERROR: _color_wrapper(colorama.Fore.LIGHTRED_EX),
                 logging.WARNING: _color_wrapper(colorama.Fore.YELLOW),
                 logging.INFO: _color_wrapper(colorama.Fore.GREEN),
                 logging.DEBUG: _color_wrapper(colorama.Fore.CYAN)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knack-0.5.4/setup.py new/knack-0.6.1/setup.py
--- old/knack-0.5.4/setup.py    2019-03-29 20:11:28.000000000 +0100
+++ new/knack-0.6.1/setup.py    2019-04-26 02:11:43.000000000 +0200
@@ -9,7 +9,7 @@
 from codecs import open
 from setuptools import setup, find_packages
 
-VERSION = '0.5.4'
+VERSION = '0.6.1'
 
 DEPENDENCIES = [
     'argcomplete',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knack-0.5.4/tests/test_config.py 
new/knack-0.6.1/tests/test_config.py
--- old/knack-0.5.4/tests/test_config.py        2019-03-29 20:11:28.000000000 
+0100
+++ new/knack-0.6.1/tests/test_config.py        2019-04-26 02:11:43.000000000 
+0200
@@ -25,8 +25,9 @@
         section = 'MySection'
         option = 'myoption'
         value = 'myvalue'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        self.assertTrue(self.cli_config.has_option(section, option))
+        self.cli_config.set_to_use_local_config(True)
         self.assertTrue(self.cli_config.has_option(section, option))
 
     def test_has_option_env(self):
@@ -34,18 +35,23 @@
             section = 'MySection'
             option = 'myoption'
             self.assertTrue(self.cli_config.has_option(section, option))
+            self.cli_config.set_to_use_local_config(True)
+            self.assertTrue(self.cli_config.has_option(section, option))
 
     def test_has_option_env_no(self):
         section = 'MySection'
         option = 'myoption'
         self.assertFalse(self.cli_config.has_option(section, option))
+        self.cli_config.set_to_use_local_config(True)
+        self.assertFalse(self.cli_config.has_option(section, option))
 
     def test_get(self):
         section = 'MySection'
         option = 'myoption'
         value = 'myvalue'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        self.assertEqual(self.cli_config.get(section, option), value)
+        self.cli_config.set_to_use_local_config(True)
         self.assertEqual(self.cli_config.get(section, option), value)
 
     def test_get_env(self):
@@ -54,17 +60,28 @@
             option = 'myoption'
             value = 'myvalue'
             self.assertEqual(self.cli_config.get(section, option), value)
+            self.cli_config.set_to_use_local_config(True)
+            self.assertEqual(self.cli_config.get(section, option), value)
 
     def test_get_not_found_section(self):
         section = 'MySection'
         option = 'myoption'
         with self.assertRaises(configparser.NoSectionError):
             self.cli_config.get(section, option)
+        self.cli_config.set_to_use_local_config(True)
+        with self.assertRaises(configparser.NoSectionError):
+            self.cli_config.get(section, option)
 
     def test_get_not_found_option(self):
         section = 'MySection'
         option = 'myoption'
-        self.cli_config.config_parser.add_section(section)
+        option_other = 'option'
+        value = 'myvalue'
+        self.cli_config.set_value(section, option_other, value)
+        with self.assertRaises(configparser.NoOptionError):
+            self.cli_config.get(section, option)
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option_other, value)
         with self.assertRaises(configparser.NoOptionError):
             self.cli_config.get(section, option)
 
@@ -72,21 +89,29 @@
         section = 'MySection'
         option = 'myoption'
         self.assertEqual(self.cli_config.get(section, option, 
fallback='fallback'), 'fallback')
+        self.cli_config.set_to_use_local_config(True)
+        self.assertEqual(self.cli_config.get(section, option, 
fallback='fallback'), 'fallback')
 
     def test_getint(self):
         section = 'MySection'
         option = 'myoption'
         value = '123'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        self.assertEqual(self.cli_config.getint(section, option), int(value))
+        self.cli_config.set_to_use_local_config(True)
         self.assertEqual(self.cli_config.getint(section, option), int(value))
 
     def test_getint_error(self):
         section = 'MySection'
         option = 'myoption'
         value = 'not_an_int'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        with self.assertRaises(ValueError):
+            self.cli_config.getint(section, option)
+        self.cli_config.set_to_use_local_config(True)
+        with self.assertRaises(ValueError):
+            self.cli_config.getint(section, option)
+        self.cli_config.set_value(section, option, value)
         with self.assertRaises(ValueError):
             self.cli_config.getint(section, option)
 
@@ -94,16 +119,20 @@
         section = 'MySection'
         option = 'myoption'
         value = '123.456'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        self.assertEqual(self.cli_config.getfloat(section, option), 
float(value))
+        self.cli_config.set_to_use_local_config(True)
         self.assertEqual(self.cli_config.getfloat(section, option), 
float(value))
 
     def test_getfloat_error(self):
         section = 'MySection'
         option = 'myoption'
         value = 'not_a_float'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        with self.assertRaises(ValueError):
+            self.cli_config.getfloat(section, option)
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option, value)
         with self.assertRaises(ValueError):
             self.cli_config.getfloat(section, option)
 
@@ -111,16 +140,20 @@
         section = 'MySection'
         option = 'myoption'
         value = 'true'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        self.assertTrue(self.cli_config.getboolean(section, option))
+        self.cli_config.set_to_use_local_config(True)
         self.assertTrue(self.cli_config.getboolean(section, option))
 
     def test_getboolean_error(self):
         section = 'MySection'
         option = 'myoption'
         value = 'not_a_boolean'
-        self.cli_config.config_parser.add_section(section)
-        self.cli_config.config_parser.set(section, option, value)
+        self.cli_config.set_value(section, option, value)
+        with self.assertRaises(ValueError):
+            self.cli_config.getboolean(section, option)
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option, value)
         with self.assertRaises(ValueError):
             self.cli_config.getboolean(section, option)
 
@@ -133,14 +166,20 @@
     def test_set_config_value_duplicate_section_ok(self):
         self.cli_config.set_value('test_section', 'test_option', 'a_value')
         self.cli_config.set_value('test_section', 'test_option_another', 
'another_value')
-        config = get_config_parser()
-        config.read(self.cli_config.config_path)
-        self.assertEqual(config.get('test_section', 'test_option'), 'a_value')
-        self.assertEqual(config.get('test_section', 'test_option_another'), 
'another_value')
+        self.assertEqual(self.cli_config.get('test_section', 'test_option'), 
'a_value')
+        self.assertEqual(self.cli_config.get('test_section', 
'test_option_another'), 'another_value')
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value('test_section', 'test_option', 'a_value')
+        self.cli_config.set_value('test_section', 'test_option_another', 
'another_value')
+        self.assertEqual(self.cli_config.get('test_section', 'test_option'), 
'a_value')
+        self.assertEqual(self.cli_config.get('test_section', 
'test_option_another'), 'another_value')
 
     def test_set_config_value_not_string(self):
         with self.assertRaises(TypeError):
             self.cli_config.set_value('test_section', 'test_option', False)
+        self.cli_config.set_to_use_local_config(True)
+        with self.assertRaises(TypeError):
+            self.cli_config.set_value('test_section', 'test_option', False)
 
     def test_set_config_value_file_permissions(self):
         self.cli_config.set_value('test_section', 'test_option', 'a_value')
@@ -155,6 +194,90 @@
         self.assertFalse(bool(file_mode & stat.S_IWOTH))
         self.assertFalse(bool(file_mode & stat.S_IXOTH))
 
+    def test_has_option_local(self):
+        section = 'MySection'
+        option = 'myoption'
+        value = 'myvalue'
+        # check local config
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option, value)
+        self.assertTrue(self.cli_config.has_option(section, option))
+        # check default config
+        self.cli_config.set_to_use_local_config(False)
+        self.assertFalse(self.cli_config.has_option(section, option))
+        self.cli_config.set_value(section, option, value)
+        self.assertTrue(self.cli_config.has_option(section, option))
+
+    def test_get_local(self):
+        section = 'MySection'
+        option = 'myoption'
+        value = 'myvalue'
+        local_value = 'localvalue'
+        # check local config
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option, local_value)
+        self.assertEqual(self.cli_config.get(section, option), local_value)
+        # check default config
+        self.cli_config.set_to_use_local_config(False)
+        self.assertFalse(self.cli_config.has_option(section, option))
+        self.cli_config.set_value(section, option, value)
+        self.assertEqual(self.cli_config.get(section, option), value)
+
+    def test_getint_local(self):
+        section = 'MySection'
+        option = 'myoption'
+        value = '123'
+        local_value = '1234'
+        # check local config
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option, local_value)
+        self.assertEqual(self.cli_config.getint(section, option), 
int(local_value))
+        # check default config
+        self.cli_config.set_to_use_local_config(False)
+        self.assertFalse(self.cli_config.has_option(section, option))
+        self.cli_config.set_value(section, option, value)
+        self.assertEqual(self.cli_config.getint(section, option), int(value))
+
+    def test_getfloat_local(self):
+        section = 'MySection'
+        option = 'myoption'
+        value = '123.456'
+        local_value = '1234.56'
+        # check local config
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option, local_value)
+        self.assertEqual(self.cli_config.getfloat(section, option), 
float(local_value))
+        # check default config
+        self.cli_config.set_to_use_local_config(False)
+        self.assertFalse(self.cli_config.has_option(section, option))
+        self.cli_config.set_value(section, option, value)
+        self.assertEqual(self.cli_config.getfloat(section, option), 
float(value))
+
+    def test_getboolean_local(self):
+        section = 'MySection'
+        option = 'myoption'
+        local_value = 'true'
+        value = 'false'
+        # check local config
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value(section, option, local_value)
+        self.assertTrue(self.cli_config.getboolean(section, option))
+        # check default config
+        self.cli_config.set_to_use_local_config(False)
+        self.assertFalse(self.cli_config.has_option(section, option))
+        self.cli_config.set_value(section, option, value)
+        self.assertFalse(self.cli_config.getboolean(section, option))
+
+    def test_set_config_value_duplicate_section_ok_local(self):
+        self.cli_config.set_to_use_local_config(True)
+        self.cli_config.set_value('test_section', 'test_option', 'a_value')
+        self.cli_config.set_value('test_section', 'test_option_another', 
'another_value')
+        self.assertEqual(self.cli_config.get('test_section', 'test_option'), 
'a_value')
+        self.assertEqual(self.cli_config.get('test_section', 
'test_option_another'), 'another_value')
+        self.cli_config.set_to_use_local_config(False)
+        self.assertFalse(self.cli_config.has_option('test_section', 
'test_option'))
+        self.assertFalse(self.cli_config.has_option('test_section', 
'test_option_another'))
+
 
 if __name__ == '__main__':
     unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/knack-0.5.4/tests/test_log.py 
new/knack-0.6.1/tests/test_log.py
--- old/knack-0.5.4/tests/test_log.py   2019-03-29 20:11:28.000000000 +0100
+++ new/knack-0.6.1/tests/test_log.py   2019-04-26 02:11:43.000000000 +0200
@@ -85,7 +85,7 @@
 
 
 class TestCustomStreamHandler(unittest.TestCase):
-    expectation = {logging.CRITICAL: colorama.Fore.RED, logging.ERROR: 
colorama.Fore.RED,
+    expectation = {logging.CRITICAL: colorama.Fore.LIGHTRED_EX, logging.ERROR: 
colorama.Fore.LIGHTRED_EX,
                    logging.WARNING: colorama.Fore.YELLOW, logging.INFO: 
colorama.Fore.GREEN,
                    logging.DEBUG: colorama.Fore.CYAN}
 


Reply via email to