Hello community,

here is the log from the commit of package python-osc-lib for openSUSE:Factory 
checked in at 2019-11-06 14:06:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-osc-lib (Old)
 and      /work/SRC/openSUSE:Factory/.python-osc-lib.new.2990 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-osc-lib"

Wed Nov  6 14:06:13 2019 rev:10 rq:745413 version:1.14.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-osc-lib/python-osc-lib.changes    
2019-05-03 22:42:00.435188498 +0200
+++ /work/SRC/openSUSE:Factory/.python-osc-lib.new.2990/python-osc-lib.changes  
2019-11-06 14:06:15.688795797 +0100
@@ -1,0 +2,19 @@
+Wed Oct  9 12:50:28 UTC 2019 - cloud-de...@suse.de
+
+- update to version 1.14.1
+  - Corrent using auth_type=none in clouds.yaml
+  - Add Python 3 Train unit tests
+  - Add error message when occurrence Forbidden error
+  - Dropping the py35 testing
+  - format_dict() returns no value for None
+  - Updates for OpenDev transition
+  - Fix usage of NotFound exception
+  - Handle nested dicts in format_dict()
+  - Add FakeModule from OSC
+  - Final switch to stestr
+  - Move the _tag module from OSC to osc-lib
+  - Cleanups to prepare for OSC 4 release
+  - Update master for stable/stein
+  - OpenDev Migration Patch
+
+-------------------------------------------------------------------

Old:
----
  osc-lib-1.12.1.tar.gz

New:
----
  osc-lib-1.14.1.tar.gz

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

Other differences:
------------------
++++++ python-osc-lib.spec ++++++
--- /var/tmp/diff_new_pack.aF7irN/_old  2019-11-06 14:06:16.448796593 +0100
+++ /var/tmp/diff_new_pack.aF7irN/_new  2019-11-06 14:06:16.452796597 +0100
@@ -17,15 +17,14 @@
 
 
 Name:           python-osc-lib
-Version:        1.12.1
+Version:        1.14.1
 Release:        0
 Summary:        OpenStackClient Library
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://docs.openstack.org/developer/osc-lib
-Source0:        
https://files.pythonhosted.org/packages/source/o/osc-lib/osc-lib-1.12.1.tar.gz
+Source0:        
https://files.pythonhosted.org/packages/source/o/osc-lib/osc-lib-1.14.1.tar.gz
 BuildRequires:  openstack-macros
-BuildRequires:  python-devel
 BuildRequires:  python2-Babel >= 2.3.4
 BuildRequires:  python2-cliff >= 2.8.0
 BuildRequires:  python2-fixtures
@@ -45,7 +44,6 @@
 BuildRequires:  python2-testtools
 BuildRequires:  python3-Babel >= 2.3.4
 BuildRequires:  python3-cliff >= 2.8.0
-BuildRequires:  python3-devel
 BuildRequires:  python3-fixtures
 BuildRequires:  python3-keystoneauth1 >= 3.7.0
 BuildRequires:  python3-mock
@@ -81,16 +79,16 @@
 %package -n python-osc-lib-doc
 Summary:        Documentation for the OpenStack client library
 Group:          Development/Languages/Python
-BuildRequires:  python-Sphinx
-BuildRequires:  python-openstackdocstheme
-BuildRequires:  python-reno
-BuildRequires:  python-sphinxcontrib-apidoc
+BuildRequires:  python3-Sphinx
+BuildRequires:  python3-openstackdocstheme
+BuildRequires:  python3-reno
+BuildRequires:  python3-sphinxcontrib-apidoc
 
 %description -n python-osc-lib-doc
 Documentation for the OpenStack client library.
 
 %prep
-%autosetup -p1 -n osc-lib-1.12.1
+%autosetup -p1 -n osc-lib-1.14.1
 %py_req_cleanup
 
 %build
@@ -100,7 +98,7 @@
 %{python_install}
 
 # generate html docs
-PBR_VERSION=%version PYTHONPATH=. sphinx-build -a -E -d doc/build/doctrees -b 
html doc/source doc/build/html
+PBR_VERSION=%{version} PYTHONPATH=. %sphinx_build -a -E -d doc/build/doctrees 
-b html doc/source doc/build/html
 # remove the sphinx-build leftovers
 rm -rf doc/build/html/.{doctrees,buildinfo}
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.aF7irN/_old  2019-11-06 14:06:16.500796647 +0100
+++ /var/tmp/diff_new_pack.aF7irN/_new  2019-11-06 14:06:16.504796652 +0100
@@ -1,8 +1,8 @@
 <services>
   <service mode="disabled" name="renderspec">
-    <param 
name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/stein/openstack/osc-lib/osc-lib.spec.j2</param>
+    <param 
name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/train/openstack/osc-lib/osc-lib.spec.j2</param>
     <param name="output-name">python-osc-lib.spec</param>
-    <param 
name="requirements">https://raw.githubusercontent.com/openstack/osc-lib/stable/stein/requirements.txt</param>
+    <param 
name="requirements">https://raw.githubusercontent.com/openstack/osc-lib/stable/train/requirements.txt</param>
     <param name="changelog-email">cloud-de...@suse.de</param>
     <param name="changelog-provider">gh,openstack,osc-lib</param>
   </service>

++++++ osc-lib-1.12.1.tar.gz -> osc-lib-1.14.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/.zuul.yaml 
new/osc-lib-1.14.1/.zuul.yaml
--- old/osc-lib-1.12.1/.zuul.yaml       2019-03-01 02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/.zuul.yaml       2019-09-11 16:28:13.000000000 +0200
@@ -5,9 +5,7 @@
       - lib-forward-testing-python3
       - openstack-lower-constraints-jobs
       - openstack-python-jobs
-      - openstack-python35-jobs
-      - openstack-python36-jobs
-      - openstack-python37-jobs
+      - openstack-python3-train-jobs
       - osc-tox-unit-tips
       - publish-openstack-docs-pti
       - release-notes-jobs-python3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/AUTHORS new/osc-lib-1.14.1/AUTHORS
--- old/osc-lib-1.12.1/AUTHORS  2019-03-01 02:34:12.000000000 +0100
+++ new/osc-lib-1.14.1/AUTHORS  2019-09-11 16:29:05.000000000 +0200
@@ -12,6 +12,7 @@
 Amey Bhide <abh...@vmware.com>
 Andreas Jaeger <a...@suse.com>
 Andreas Jaeger <a...@suse.de>
+Andrey Kurilin <andr.kuri...@gmail.com>
 Atsushi SAKAI <sak...@jp.fujitsu.com>
 Bar Elharar <elhar...@gmail.com>
 Bharat Kunwar <b.kun...@gmail.com>
@@ -25,6 +26,7 @@
 Chuck Short <chuck.sh...@canonical.com>
 Clark Boylan <clark.boy...@gmail.com>
 Colleen Murphy <coll...@puppetlabs.com>
+Corey Bryant <corey.bry...@canonical.com>
 Cyril Roelandt <cyril.roela...@enovance.com>
 Daisuke Fujita <fuzita.dais...@jp.fujitsu.com>
 Daniel Gonzalez <dan...@gonzalez-nothnagel.de>
@@ -34,11 +36,13 @@
 David Moreau Simard <dmsim...@iweb.com>
 Dean Troyer <dtro...@gmail.com>
 Dina Belova <dbel...@mirantis.com>
+Dmitry Tantsur <dtant...@protonmail.com>
 Doug Hellmann <doug.hellm...@dreamhost.com>
 Doug Hellmann <d...@doughellmann.com>
 Dougal Matthews <dou...@redhat.com>
 Eric Brown <bro...@vmware.com>
 Florent Flament <florent.flament-...@cloudwatt.com>
+Ghanshyam Mann <gm...@ghanshyammann.com>
 Guojian Shao <guoj...@unitedstack.com>
 Hangdong Zhang <hdzh...@fiberhome.com>
 Hidekazu Nakamura <hid-nakam...@vf.jp.nec.com>
@@ -78,6 +82,7 @@
 Matt Riedemann <mrie...@us.ibm.com>
 Matthew Treinish <mtrein...@kortar.org>
 Matthieu Huin <m...@enovance.com>
+Michael Johnson <johnso...@gmail.com>
 Michael McCune <m...@redhat.com>
 Monty Taylor <mord...@inaugust.com>
 Mouad Benchchaoui <m.benchcha...@x-ion.de>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/ChangeLog new/osc-lib-1.14.1/ChangeLog
--- old/osc-lib-1.12.1/ChangeLog        2019-03-01 02:34:12.000000000 +0100
+++ new/osc-lib-1.14.1/ChangeLog        2019-09-11 16:29:05.000000000 +0200
@@ -1,6 +1,32 @@
 CHANGES
 =======
 
+1.14.1
+------
+
+* format\_dict() returns no value for None
+* Handle nested dicts in format\_dict()
+
+1.14.0
+------
+
+* Cleanups to prepare for OSC 4 release
+* Fix usage of NotFound exception
+* Add error message when occurrence Forbidden error
+* Add Python 3 Train unit tests
+
+1.13.0
+------
+
+* Corrent using auth\_type=none in clouds.yaml
+* Add FakeModule from OSC
+* Move the \_tag module from OSC to osc-lib
+* Final switch to stestr
+* Dropping the py35 testing
+* Updates for OpenDev transition
+* OpenDev Migration Patch
+* Update master for stable/stein
+
 1.12.1
 ------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/PKG-INFO new/osc-lib-1.14.1/PKG-INFO
--- old/osc-lib-1.12.1/PKG-INFO 2019-03-01 02:34:12.000000000 +0100
+++ new/osc-lib-1.14.1/PKG-INFO 2019-09-11 16:29:05.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: osc-lib
-Version: 1.12.1
+Version: 1.14.1
 Summary: OpenStackClient Library
 Home-page: https://docs.openstack.org/osc-lib/latest/
 Author: OpenStack
@@ -32,7 +32,7 @@
         .. _Online Documentation: http://docs.openstack.org/osc-lib/latest/
         .. _Launchpad project: https://launchpad.net/python-openstackclient
         .. _Bugs: https://storyboard.openstack.org/#!/project_group/80
-        .. _Source: https://git.openstack.org/cgit/openstack/osc-lib
+        .. _Source: https://opendev.org/openstack/osc-lib
         .. _Developer: 
http://docs.openstack.org/project-team-guide/project-setup/python.html
         .. _Contributing: 
http://docs.openstack.org/infra/manual/developers.html
         .. _Testing: 
http://docs.openstack.org/osc-lib/latest/contributor/#testing
@@ -81,4 +81,5 @@
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/README.rst 
new/osc-lib-1.14.1/README.rst
--- old/osc-lib-1.12.1/README.rst       2019-03-01 02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/README.rst       2019-09-11 16:28:13.000000000 +0200
@@ -24,7 +24,7 @@
 .. _Online Documentation: http://docs.openstack.org/osc-lib/latest/
 .. _Launchpad project: https://launchpad.net/python-openstackclient
 .. _Bugs: https://storyboard.openstack.org/#!/project_group/80
-.. _Source: https://git.openstack.org/cgit/openstack/osc-lib
+.. _Source: https://opendev.org/openstack/osc-lib
 .. _Developer: 
http://docs.openstack.org/project-team-guide/project-setup/python.html
 .. _Contributing: http://docs.openstack.org/infra/manual/developers.html
 .. _Testing: http://docs.openstack.org/osc-lib/latest/contributor/#testing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/doc/source/contributor/index.rst 
new/osc-lib-1.14.1/doc/source/contributor/index.rst
--- old/osc-lib-1.12.1/doc/source/contributor/index.rst 2019-03-01 
02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/doc/source/contributor/index.rst 2019-09-11 
16:28:13.000000000 +0200
@@ -9,7 +9,7 @@
 :code:`openstack/osc-lib` project using `Gerrit`_.
 Developers may also be found in the `IRC channel`_ ``#openstack-sdks``.
 
-.. _`on OpenStack's Git server`: 
https://git.openstack.org/cgit/openstack/python-openstackclient/tree
+.. _`on OpenStack's Git server`: 
https://opendev.org/openstack/python-openstackclient/tree
 .. _Launchpad: https://launchpad.net/python-openstackclient
 .. _Gerrit: 
http://docs.openstack.org/infra/manual/developers.html#development-workflow
 .. _Bug reports: https://storyboard.openstack.org/#!/project_group/80
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/api/api.py 
new/osc-lib-1.14.1/osc_lib/api/api.py
--- old/osc-lib-1.12.1/osc_lib/api/api.py       2019-03-01 02:31:55.000000000 
+0100
+++ new/osc-lib-1.14.1/osc_lib/api/api.py       2019-09-11 16:28:13.000000000 
+0200
@@ -361,7 +361,7 @@
         num_bulk = len(bulk_list)
         if num_bulk == 0:
             msg = _("none found")
-            raise exceptions.NotFound(msg)
+            raise exceptions.NotFound(404, msg)
         elif num_bulk > 1:
             msg = _("many found")
             raise RuntimeError(msg)
@@ -388,7 +388,7 @@
 
         def raise_not_found():
             msg = _("%s not found") % value
-            raise exceptions.NotFound(msg)
+            raise exceptions.NotFound(404, msg)
 
         try:
             ret = self._request(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/api/auth.py 
new/osc-lib-1.14.1/osc_lib/api/auth.py
--- old/osc-lib-1.12.1/osc_lib/api/auth.py      2019-03-01 02:31:55.000000000 
+0100
+++ new/osc-lib-1.14.1/osc_lib/api/auth.py      2019-09-11 16:28:13.000000000 
+0200
@@ -101,7 +101,7 @@
     msgs = []
 
     # when no auth params are passed in, user advised to use os-cloud
-    if not options.auth:
+    if not options.auth and auth_plugin_name != 'none':
         msgs.append(_(
             'Set a cloud-name with --os-cloud or OS_CLOUD'
         ))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/cli/client_config.py 
new/osc-lib-1.14.1/osc_lib/cli/client_config.py
--- old/osc-lib-1.12.1/osc_lib/cli/client_config.py     2019-03-01 
02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib/cli/client_config.py     2019-09-11 
16:28:13.000000000 +0200
@@ -162,10 +162,6 @@
                       strutils.mask_password(six.text_type(config)))
         return config
 
-    def _validate_auth_ksc(self, config, cloud, fixed_argparse=None):
-        """Old compatibility hack for OSC, no longer needed/wanted"""
-        return config
-
     def _validate_auth(self, config, loader, fixed_argparse=None):
         """Validate auth plugin arguments"""
         # May throw a keystoneauth1.exceptions.NoMatchingPlugin
@@ -226,3 +222,11 @@
                 config['auth'][p_opt.dest] = self._pw_callback(p_opt.prompt)
 
         return config
+
+    def load_auth_plugin(self, config):
+        """Get auth plugin and validate args"""
+
+        loader = self._get_auth_loader(config)
+        config = self._validate_auth(config, loader)
+        auth_plugin = loader.load_from_options(**config['auth'])
+        return auth_plugin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/clientmanager.py 
new/osc-lib-1.14.1/osc_lib/clientmanager.py
--- old/osc-lib-1.12.1/osc_lib/clientmanager.py 2019-03-01 02:31:55.000000000 
+0100
+++ new/osc-lib-1.14.1/osc_lib/clientmanager.py 2019-09-11 16:28:13.000000000 
+0200
@@ -202,9 +202,15 @@
             self._auth_ref = self.auth.get_auth_ref(self.session)
         return self._auth_ref
 
+    def _override_for(self, service_type):
+        key = '%s_endpoint_override' % service_type.replace('-', '_')
+        return self._cli_options.config.get(key)
+
     def is_service_available(self, service_type):
         """Check if a service type is in the current Service Catalog"""
-
+        # If there is an override, assume the service is available
+        if self._override_for(service_type):
+            return True
         # Trigger authentication necessary to discover endpoint
         if self.auth_ref:
             service_catalog = self.auth_ref.service_catalog
@@ -226,6 +232,11 @@
     def get_endpoint_for_service_type(self, service_type, region_name=None,
                                       interface='public'):
         """Return the endpoint URL for the service type."""
+        # Overrides take priority unconditionally
+        override = self._override_for(service_type)
+        if override:
+            return override
+
         if not interface:
             interface = 'public'
         # See if we are using password flow auth, i.e. we have a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/exceptions.py 
new/osc-lib-1.14.1/osc_lib/exceptions.py
--- old/osc-lib-1.12.1/osc_lib/exceptions.py    2019-03-01 02:31:55.000000000 
+0100
+++ new/osc-lib-1.14.1/osc_lib/exceptions.py    2019-09-11 16:28:13.000000000 
+0200
@@ -55,6 +55,9 @@
     """The base exception class for all exceptions this library raises."""
 
     def __init__(self, code, message=None, details=None):
+        if not isinstance(code, int) and message is None:
+            message = code
+            code = self.http_status
         self.code = code
         self.message = message or self.__class__.message
         self.details = details
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/shell.py 
new/osc-lib-1.14.1/osc_lib/shell.py
--- old/osc-lib-1.12.1/osc_lib/shell.py 2019-03-01 02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib/shell.py 2019-09-11 16:28:13.000000000 +0200
@@ -410,6 +410,7 @@
             self.cloud_config = cloud_config.OSC_Config(
                 pw_func=prompt_for_password,
                 override_defaults={
+                    'interface': None,
                     'auth_type': self._auth_type,
                 },
             )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/tests/fakes.py 
new/osc-lib-1.14.1/osc_lib/tests/fakes.py
--- old/osc-lib-1.12.1/osc_lib/tests/fakes.py   2019-03-01 02:31:55.000000000 
+0100
+++ new/osc-lib-1.14.1/osc_lib/tests/fakes.py   2019-09-11 16:28:13.000000000 
+0200
@@ -143,6 +143,16 @@
         }
 
 
+class FakeModule(object):
+
+    def __init__(self, name, version):
+        self.name = name
+        self.__version__ = version
+        # Workaround for openstacksdk case
+        self.version = mock.Mock()
+        self.version.__version__ = version
+
+
 class FakeResource(object):
 
     def __init__(self, manager=None, info=None, loaded=False, methods=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/tests/test_clientmanager.py 
new/osc-lib-1.14.1/osc_lib/tests/test_clientmanager.py
--- old/osc-lib-1.12.1/osc_lib/tests/test_clientmanager.py      2019-03-01 
02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib/tests/test_clientmanager.py      2019-09-11 
16:28:13.000000000 +0200
@@ -419,6 +419,31 @@
         self.assertEqual(client_manager.auth.project_id, fakes.PROJECT_ID)
         self.assertTrue(client_manager._auth_setup_completed)
 
+    def test_client_manager_none_auth(self):
+        # test token auth
+        client_manager = self._make_clientmanager(
+            auth_args={},
+            auth_plugin_name='none',
+        )
+        self.assertIsNone(
+            client_manager.get_endpoint_for_service_type('compute'))
+
+    def test_client_manager_endpoint_override(self):
+        # test token auth
+        client_manager = self._make_clientmanager(
+            auth_args={},
+            config_args={'compute_endpoint_override': 'http://example.com',
+                         'foo_bar_endpoint_override': 'http://example2.com'},
+            auth_plugin_name='none',
+        )
+        self.assertEqual(
+            'http://example.com',
+            client_manager.get_endpoint_for_service_type('compute'))
+        self.assertEqual(
+            'http://example2.com',
+            client_manager.get_endpoint_for_service_type('foo-bar'))
+        self.assertTrue(client_manager.is_service_available('compute'))
+
 
 class TestClientManagerSDK(utils.TestClientManager):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/tests/utils/test_tags.py 
new/osc-lib-1.14.1/osc_lib/tests/utils/test_tags.py
--- old/osc-lib-1.12.1/osc_lib/tests/utils/test_tags.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib/tests/utils/test_tags.py 2019-09-11 
16:28:13.000000000 +0200
@@ -0,0 +1,171 @@
+#   Copyright 2019 Red Hat, Inc. All rights reserved.
+#
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+
+import argparse
+import mock
+
+from osc_lib.tests import utils as test_utils
+from osc_lib.utils import tags
+
+
+class TestTags(test_utils.TestCase):
+
+    def test_add_tag_filtering_option_to_parser(self):
+        parser = argparse.ArgumentParser()
+        tags.add_tag_filtering_option_to_parser(parser, 'test')
+
+        parsed_args = parser.parse_args(['--tags', 'tag1,tag2',
+                                         '--any-tags', 'tag4',
+                                         '--not-tags', 'tag5',
+                                         '--not-any-tags', 'tag6'])
+
+        actual = getattr(parsed_args, 'tags', [])
+        expected = ['tag1', 'tag2']
+        self.assertItemsEqual(expected, actual)
+
+        actual = getattr(parsed_args, 'any_tags', [])
+        expected = ['tag4']
+        self.assertItemsEqual(expected, actual)
+
+        actual = getattr(parsed_args, 'not_tags', [])
+        expected = ['tag5']
+        self.assertItemsEqual(expected, actual)
+
+        actual = getattr(parsed_args, 'not_any_tags', [])
+        expected = ['tag6']
+        self.assertItemsEqual(expected, actual)
+
+    def test_get_tag_filtering_args(self):
+        parser = argparse.ArgumentParser()
+        tags.add_tag_filtering_option_to_parser(parser, 'test')
+
+        parsed_args = parser.parse_args(['--tags', 'tag1,tag2',
+                                         '--any-tags', 'tag4',
+                                         '--not-tags', 'tag5',
+                                         '--not-any-tags', 'tag6'])
+        expected = {'tags': 'tag1,tag2', 'any_tags': 'tag4',
+                    'not_tags': 'tag5', 'not_any_tags': 'tag6'}
+        args = {}
+        tags.get_tag_filtering_args(parsed_args, args)
+        self.assertEqual(expected, args)
+
+    def test_add_tag_option_to_parser_for_create(self):
+        parser = argparse.ArgumentParser()
+        tags.add_tag_option_to_parser_for_create(parser, 'test')
+
+        # Test that --tag and --no-tag are mutually exclusive
+        self.assertRaises(SystemExit, parser.parse_args,
+                          ['--tag', 'tag1', '--no-tag'])
+
+        parsed_args = parser.parse_args(['--tag', 'tag1'])
+        actual = getattr(parsed_args, 'tags', [])
+        expected = ['tag1']
+        self.assertItemsEqual(expected, actual)
+
+        parsed_args = parser.parse_args(['--no-tag'])
+        actual = getattr(parsed_args, 'no-tag', [])
+        expected = []
+        self.assertItemsEqual(expected, actual)
+
+    def test_add_tag_option_to_parser_for_set(self):
+        parser = argparse.ArgumentParser()
+        tags.add_tag_option_to_parser_for_set(parser, 'test')
+
+        parsed_args = parser.parse_args(['--tag', 'tag1'])
+        actual = getattr(parsed_args, 'tags', [])
+        expected = ['tag1']
+        self.assertItemsEqual(expected, actual)
+
+        parsed_args = parser.parse_args(['--no-tag'])
+        actual = getattr(parsed_args, 'no-tag', [])
+        expected = []
+        self.assertItemsEqual(expected, actual)
+
+    def test_add_tag_option_to_parser_for_unset(self):
+        parser = argparse.ArgumentParser()
+        tags.add_tag_option_to_parser_for_unset(parser, 'test')
+
+        # Test that --tag and --all-tag are mutually exclusive
+        self.assertRaises(SystemExit, parser.parse_args,
+                          ['--tag', 'tag1', '--all-tag'])
+
+        parsed_args = parser.parse_args(['--tag', 'tag1'])
+        actual = getattr(parsed_args, 'tags', [])
+        expected = ['tag1']
+        self.assertItemsEqual(expected, actual)
+
+        parsed_args = parser.parse_args(['--all-tag'])
+        actual = getattr(parsed_args, 'all-tag', [])
+        expected = []
+        self.assertItemsEqual(expected, actual)
+
+    def test_update_tags_for_set(self):
+        mock_client = mock.MagicMock()
+        mock_obj = mock.MagicMock()
+        mock_parsed_args = mock.MagicMock()
+
+        # no-tag True path
+        mock_parsed_args.no_tag = True
+        mock_parsed_args.tags = ['tag1']
+        mock_obj.tags = None
+        tags.update_tags_for_set(mock_client, mock_obj, mock_parsed_args)
+        mock_client.set_tags.assert_called_once_with(
+            mock_obj, list(mock_parsed_args.tags))
+
+        # no-tag False path
+        mock_client.set_tags.reset_mock()
+        mock_parsed_args.no_tag = False
+        mock_parsed_args.tags = ['tag1']
+        mock_obj.tags = ['tag2']
+        expected_list = ['tag1', 'tag2']
+        tags.update_tags_for_set(mock_client, mock_obj, mock_parsed_args)
+        mock_client.set_tags.assert_called_once_with(
+            mock_obj, expected_list)
+
+        # no new tags path
+        mock_client.set_tags.reset_mock()
+        mock_parsed_args.no_tag = False
+        mock_parsed_args.tags = None
+        mock_obj.tags = ['tag2']
+        tags.update_tags_for_set(mock_client, mock_obj, mock_parsed_args)
+        mock_client.set_tags.assert_not_called()
+
+    def test_update_tags_for_unset(self):
+        mock_client = mock.MagicMock()
+        mock_obj = mock.MagicMock()
+        mock_parsed_args = mock.MagicMock()
+
+        # No new tags
+        mock_obj.tags = ['tag1']
+        mock_parsed_args.all_tag = False
+        mock_parsed_args.tags = None
+        tags.update_tags_for_unset(mock_client, mock_obj, mock_parsed_args)
+        mock_client.set_tags.assert_not_called()
+
+        # Clear all tags
+        mock_obj.tags = ['tag1']
+        mock_parsed_args.all_tag = True
+        mock_parsed_args.tags = None
+        tags.update_tags_for_unset(mock_client, mock_obj, mock_parsed_args)
+        mock_client.set_tags.assert_called_once_with(
+            mock_obj, [])
+
+        # Remove one tag
+        mock_client.set_tags.reset_mock()
+        mock_obj.tags = ['tag1', 'tag2']
+        mock_parsed_args.all_tag = False
+        mock_parsed_args.tags = ['tag2']
+        tags.update_tags_for_unset(mock_client, mock_obj, mock_parsed_args)
+        mock_client.set_tags.assert_called_once_with(
+            mock_obj, ['tag1'])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/tests/utils/test_utils.py 
new/osc-lib-1.14.1/osc_lib/tests/utils/test_utils.py
--- old/osc-lib-1.12.1/osc_lib/tests/utils/test_utils.py        2019-03-01 
02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib/tests/utils/test_utils.py        2019-09-11 
16:28:13.000000000 +0200
@@ -689,6 +689,50 @@
                          utils.format_dict({'e': 'f', 'c': 'd', 'a': 'b'}))
         self.assertIsNone(utils.format_dict(None))
 
+    def test_format_dict_recursive(self):
+        expected = "a='b', c.1='d', c.2=''"
+        self.assertEqual(
+            expected,
+            utils.format_dict({'a': 'b', 'c': {'1': 'd', '2': ''}})
+        )
+        self.assertEqual(
+            expected,
+            utils.format_dict({'c': {'1': 'd', '2': ''}, 'a': 'b'})
+        )
+        self.assertIsNone(utils.format_dict(None))
+
+        expected = "a1='A', a2.b1.c1='B', a2.b1.c2=, a2.b2='D'"
+        self.assertEqual(
+            expected,
+            utils.format_dict(
+                {
+                    'a1': 'A',
+                    'a2': {
+                        'b1': {
+                            'c1': 'B',
+                            'c2': None,
+                        },
+                        'b2': 'D',
+                    },
+                }
+            )
+        )
+        self.assertEqual(
+            expected,
+            utils.format_dict(
+                {
+                    'a2': {
+                        'b1': {
+                            'c2': None,
+                            'c1': 'B',
+                        },
+                        'b2': 'D',
+                    },
+                    'a1': 'A',
+                }
+            )
+        )
+
     def test_format_dict_of_list(self):
         expected = "a=a1, a2; b=b1, b2; c=c1, c2; e="
         self.assertEqual(expected,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/utils/__init__.py 
new/osc-lib-1.14.1/osc_lib/utils/__init__.py
--- old/osc-lib-1.12.1/osc_lib/utils/__init__.py        2019-03-01 
02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib/utils/__init__.py        2019-09-11 
16:28:13.000000000 +0200
@@ -261,6 +261,16 @@
                 'resource': manager.resource_class.__name__.lower(),
                 'id': name_or_id,
             })
+
+        if type(ex).__name__ == 'Forbidden':
+            msg = _(
+                "You are not authorized to find %(resource)s with the "
+                "name '%(id)s'."
+            )
+            raise exceptions.CommandError(msg % {
+                'resource': manager.resource_class.__name__.lower(),
+                'id': name_or_id,
+            })
         else:
             pass
 
@@ -284,10 +294,11 @@
         raise exceptions.CommandError(msg % name_or_id)
 
 
-def format_dict(data):
+def format_dict(data, prefix=None):
     """Return a formatted string of key value pairs
 
     :param data: a dict
+    :param prefix: the current parent keys in a recursive call
     :rtype: a string formatted to key='value'
     """
 
@@ -296,7 +307,18 @@
 
     output = ""
     for s in sorted(data):
-        output = output + s + "='" + six.text_type(data[s]) + "', "
+        if prefix:
+            key_str = ".".join([prefix, s])
+        else:
+            key_str = s
+        if isinstance(data[s], dict):
+            # NOTE(dtroyer): Only append the separator chars here, quoting
+            #                is completely handled in the terminal case.
+            output = output + format_dict(data[s], prefix=key_str) + ", "
+        elif data[s] is not None:
+            output = output + key_str + "='" + six.text_type(data[s]) + "', "
+        else:
+            output = output + key_str + "=, "
     return output[:-2]
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib/utils/tags.py 
new/osc-lib-1.14.1/osc_lib/utils/tags.py
--- old/osc-lib-1.12.1/osc_lib/utils/tags.py    1970-01-01 01:00:00.000000000 
+0100
+++ new/osc-lib-1.14.1/osc_lib/utils/tags.py    2019-09-11 16:28:13.000000000 
+0200
@@ -0,0 +1,174 @@
+#   Licensed under the Apache License, Version 2.0 (the "License"); you may
+#   not use this file except in compliance with the License. You may obtain
+#   a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#   License for the specific language governing permissions and limitations
+#   under the License.
+#
+
+import argparse
+
+from osc_lib.i18n import _
+
+
+class _CommaListAction(argparse.Action):
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        setattr(namespace, self.dest, values.split(','))
+
+
+def add_tag_filtering_option_to_parser(parser, resource_name):
+    """Add tag filtering options to a parser.
+
+    :param parser: argparse.Argument parser object.
+    :param resource_name: Description of the object being filtered.
+    """
+    parser.add_argument(
+        '--tags',
+        metavar='<tag>[,<tag>,...]',
+        action=_CommaListAction,
+        help=_('List %s which have all given tag(s) '
+               '(Comma-separated list of tags)') % resource_name
+    )
+    parser.add_argument(
+        '--any-tags',
+        metavar='<tag>[,<tag>,...]',
+        action=_CommaListAction,
+        help=_('List %s which have any given tag(s) '
+               '(Comma-separated list of tags)') % resource_name
+    )
+    parser.add_argument(
+        '--not-tags',
+        metavar='<tag>[,<tag>,...]',
+        action=_CommaListAction,
+        help=_('Exclude %s which have all given tag(s) '
+               '(Comma-separated list of tags)') % resource_name
+    )
+    parser.add_argument(
+        '--not-any-tags',
+        metavar='<tag>[,<tag>,...]',
+        action=_CommaListAction,
+        help=_('Exclude %s which have any given tag(s) '
+               '(Comma-separated list of tags)') % resource_name
+    )
+
+
+def get_tag_filtering_args(parsed_args, args):
+    """Adds the tag arguments to an args list.
+
+    Intended to be used to append the tags to an argument list that will be
+    used for service client.
+
+    :param parsed_args: Parsed argument object returned by argparse parse_args.
+    :param args: The argument list to add tags to.
+    """
+    if parsed_args.tags:
+        args['tags'] = ','.join(parsed_args.tags)
+    if parsed_args.any_tags:
+        args['any_tags'] = ','.join(parsed_args.any_tags)
+    if parsed_args.not_tags:
+        args['not_tags'] = ','.join(parsed_args.not_tags)
+    if parsed_args.not_any_tags:
+        args['not_any_tags'] = ','.join(parsed_args.not_any_tags)
+
+
+def add_tag_option_to_parser_for_create(parser, resource_name):
+    """Add tag options to a parser for create commands.
+
+    :param parser: argparse.Argument parser object.
+    :param resource_name: Description of the object being filtered.
+    """
+    tag_group = parser.add_mutually_exclusive_group()
+    tag_group.add_argument(
+        '--tag',
+        action='append',
+        dest='tags',
+        metavar='<tag>',
+        help=_("Tag to be added to the %s "
+               "(repeat option to set multiple tags)") % resource_name
+    )
+    tag_group.add_argument(
+        '--no-tag',
+        action='store_true',
+        help=_("No tags associated with the %s") % resource_name
+    )
+
+
+def add_tag_option_to_parser_for_set(parser, resource_name):
+    """Add tag options to a parser for set commands.
+
+    :param parser: argparse.Argument parser object.
+    :param resource_name: Description of the object being filtered.
+    """
+    parser.add_argument(
+        '--tag',
+        action='append',
+        dest='tags',
+        metavar='<tag>',
+        help=_("Tag to be added to the %s "
+               "(repeat option to set multiple tags)") % resource_name
+    )
+    parser.add_argument(
+        '--no-tag',
+        action='store_true',
+        help=_("Clear tags associated with the %s. Specify both "
+               "--tag and --no-tag to overwrite current tags") % resource_name
+    )
+
+
+def add_tag_option_to_parser_for_unset(parser, resource_name):
+    """Add tag options to a parser for set commands.
+
+    :param parser: argparse.Argument parser object.
+    :param resource_name: Description of the object being filtered.
+    """
+    tag_group = parser.add_mutually_exclusive_group()
+    tag_group.add_argument(
+        '--tag',
+        action='append',
+        dest='tags',
+        metavar='<tag>',
+        help=_("Tag to be removed from the %s "
+               "(repeat option to remove multiple tags)") % resource_name)
+    tag_group.add_argument(
+        '--all-tag',
+        action='store_true',
+        help=_("Clear all tags associated with the %s") % resource_name)
+
+
+def update_tags_for_set(client, obj, parsed_args):
+    """Set the tags on an object.
+
+    :param client: The service client to use setting the tags.
+    :param obj: The object (Resource) to set the tags on.
+    :param parsed_args: Parsed argument object returned by argparse parse_args.
+    """
+    if parsed_args.no_tag:
+        tags = set()
+    else:
+        tags = set(obj.tags or [])
+    if parsed_args.tags:
+        tags |= set(parsed_args.tags)
+    if set(obj.tags or []) != tags:
+        client.set_tags(obj, sorted(list(tags)))
+
+
+def update_tags_for_unset(client, obj, parsed_args):
+    """Unset the tags on an object.
+
+    :param client: The service client to use unsetting the tags.
+    :param obj: The object (Resource) to unset the tags on.
+    :param parsed_args: Parsed argument object returned by argparse parse_args.
+    """
+    tags = set(obj.tags)
+    if parsed_args.all_tag:
+        tags = set()
+    if parsed_args.tags:
+        tags -= set(parsed_args.tags)
+    if set(obj.tags) != tags:
+        client.set_tags(obj, sorted(list(tags)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib.egg-info/PKG-INFO 
new/osc-lib-1.14.1/osc_lib.egg-info/PKG-INFO
--- old/osc-lib-1.12.1/osc_lib.egg-info/PKG-INFO        2019-03-01 
02:34:12.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib.egg-info/PKG-INFO        2019-09-11 
16:29:05.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: osc-lib
-Version: 1.12.1
+Version: 1.14.1
 Summary: OpenStackClient Library
 Home-page: https://docs.openstack.org/osc-lib/latest/
 Author: OpenStack
@@ -32,7 +32,7 @@
         .. _Online Documentation: http://docs.openstack.org/osc-lib/latest/
         .. _Launchpad project: https://launchpad.net/python-openstackclient
         .. _Bugs: https://storyboard.openstack.org/#!/project_group/80
-        .. _Source: https://git.openstack.org/cgit/openstack/osc-lib
+        .. _Source: https://opendev.org/openstack/osc-lib
         .. _Developer: 
http://docs.openstack.org/project-team-guide/project-setup/python.html
         .. _Contributing: 
http://docs.openstack.org/infra/manual/developers.html
         .. _Testing: 
http://docs.openstack.org/osc-lib/latest/contributor/#testing
@@ -81,4 +81,5 @@
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib.egg-info/SOURCES.txt 
new/osc-lib-1.14.1/osc_lib.egg-info/SOURCES.txt
--- old/osc-lib-1.12.1/osc_lib.egg-info/SOURCES.txt     2019-03-01 
02:34:12.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib.egg-info/SOURCES.txt     2019-09-11 
16:29:05.000000000 +0200
@@ -72,16 +72,20 @@
 osc_lib/tests/command/test_timing.py
 osc_lib/tests/utils/__init__.py
 osc_lib/tests/utils/test_columns.py
+osc_lib/tests/utils/test_tags.py
 osc_lib/tests/utils/test_utils.py
 osc_lib/utils/__init__.py
 osc_lib/utils/columns.py
+osc_lib/utils/tags.py
 releasenotes/notes/.placeholder
 releasenotes/notes/1.0-summary-47dcce446d6a512b.yaml
 releasenotes/notes/add-MultiKeyValueCommaAction-class-01dd254a287d70d2.yaml
 releasenotes/notes/arg-precedence-1ba9fd6929650830.yaml
+releasenotes/notes/auth-type-none-d96760912605f822.yaml
 releasenotes/notes/bug-1558690-1528b637f2c0a449.yaml
 releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml
 releasenotes/notes/bug-2004898-686577a07e791051.yaml
+releasenotes/notes/bug-2006480-436489d39643e76c.yaml
 releasenotes/notes/direct-openstacksdk-535a179f3c645cc0.yaml
 releasenotes/notes/find-project-203bf867619c557e.yaml
 releasenotes/notes/keystone-to-keystone-9b2e55b051775322.yaml
@@ -95,6 +99,7 @@
 releasenotes/source/pike.rst
 releasenotes/source/queens.rst
 releasenotes/source/rocky.rst
+releasenotes/source/stein.rst
 releasenotes/source/unreleased.rst
 releasenotes/source/_static/.placeholder
 releasenotes/source/_templates/.placeholder
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/osc_lib.egg-info/pbr.json 
new/osc-lib-1.14.1/osc_lib.egg-info/pbr.json
--- old/osc-lib-1.12.1/osc_lib.egg-info/pbr.json        2019-03-01 
02:34:12.000000000 +0100
+++ new/osc-lib-1.14.1/osc_lib.egg-info/pbr.json        2019-09-11 
16:29:05.000000000 +0200
@@ -1 +1 @@
-{"git_version": "9b610ea", "is_release": true}
\ No newline at end of file
+{"git_version": "a0d9746", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/osc-lib-1.12.1/releasenotes/notes/auth-type-none-d96760912605f822.yaml 
new/osc-lib-1.14.1/releasenotes/notes/auth-type-none-d96760912605f822.yaml
--- old/osc-lib-1.12.1/releasenotes/notes/auth-type-none-d96760912605f822.yaml  
1970-01-01 01:00:00.000000000 +0100
+++ new/osc-lib-1.14.1/releasenotes/notes/auth-type-none-d96760912605f822.yaml  
2019-09-11 16:28:13.000000000 +0200
@@ -0,0 +1,7 @@
+---
+fixes:
+  - |
+    Fixes incorrect error when using ``auth_type: none`` in ``clouds.yaml``.
+  - |
+    Respects the ``<service type>_endpoint_override`` configuration options,
+    similarly to openstacksdk.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/osc-lib-1.12.1/releasenotes/notes/bug-2006480-436489d39643e76c.yaml 
new/osc-lib-1.14.1/releasenotes/notes/bug-2006480-436489d39643e76c.yaml
--- old/osc-lib-1.12.1/releasenotes/notes/bug-2006480-436489d39643e76c.yaml     
1970-01-01 01:00:00.000000000 +0100
+++ new/osc-lib-1.14.1/releasenotes/notes/bug-2006480-436489d39643e76c.yaml     
2019-09-11 16:28:13.000000000 +0200
@@ -0,0 +1,4 @@
+---
+fixes:
+  - Fix format_columns.format_dict() to properly re-format nested dicts.
+    [Bug `2006480 <https://storyboard.openstack.org/#!/story/2006480>`_]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/releasenotes/source/index.rst 
new/osc-lib-1.14.1/releasenotes/source/index.rst
--- old/osc-lib-1.12.1/releasenotes/source/index.rst    2019-03-01 
02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/releasenotes/source/index.rst    2019-09-11 
16:28:13.000000000 +0200
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    unreleased
+   stein
    rocky
    queens
    pike
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/releasenotes/source/stein.rst 
new/osc-lib-1.14.1/releasenotes/source/stein.rst
--- old/osc-lib-1.12.1/releasenotes/source/stein.rst    1970-01-01 
01:00:00.000000000 +0100
+++ new/osc-lib-1.14.1/releasenotes/source/stein.rst    2019-09-11 
16:28:13.000000000 +0200
@@ -0,0 +1,6 @@
+===================================
+ Stein Series Release Notes
+===================================
+
+.. release-notes::
+   :branch: stable/stein
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/setup.cfg new/osc-lib-1.14.1/setup.cfg
--- old/osc-lib-1.12.1/setup.cfg        2019-03-01 02:34:12.000000000 +0100
+++ new/osc-lib-1.14.1/setup.cfg        2019-09-11 16:29:05.000000000 +0200
@@ -16,7 +16,8 @@
        Programming Language :: Python :: 2
        Programming Language :: Python :: 2.7
        Programming Language :: Python :: 3
-       Programming Language :: Python :: 3.5
+       Programming Language :: Python :: 3.6
+       Programming Language :: Python :: 3.7
 
 [files]
 packages = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/osc-lib-1.12.1/tox.ini new/osc-lib-1.14.1/tox.ini
--- old/osc-lib-1.12.1/tox.ini  2019-03-01 02:31:55.000000000 +0100
+++ new/osc-lib-1.14.1/tox.ini  2019-09-11 16:28:13.000000000 +0200
@@ -1,6 +1,6 @@
 [tox]
 minversion = 2.0
-envlist = py35,py27,pep8
+envlist = py27,py37,pep8
 skipdist = True
 
 [testenv]
@@ -11,11 +11,11 @@
          OS_STDERR_CAPTURE=1
          OS_TEST_TIMEOUT=60
 deps =
-  
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+  
-c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/upper-constraints.txt}
   -r{toxinidir}/test-requirements.txt
   -r{toxinidir}/requirements.txt
-commands = ostestr {posargs}
-whitelist_externals = ostestr
+commands = stestr run {posargs}
+whitelist_externals = stestr
 
 [testenv:unit-tips]
 basepython = python3
@@ -24,8 +24,8 @@
     pip install -q -e "git+file://{toxinidir}/../keystoneauth#egg=keystoneauth"
     pip install -q -e "git+file://{toxinidir}/../openstacksdk#egg=openstacksdk"
     pip freeze
-    ostestr {posargs}
-whitelist_externals = ostestr
+    stestr run {posargs}
+whitelist_externals = stestr
 
 [testenv:pep8]
 basepython = python3
@@ -48,7 +48,7 @@
 [testenv:docs]
 basepython = python3
 deps =
-  
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+  
-c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/upper-constraints.txt}
   -r{toxinidir}/requirements.txt
   -r{toxinidir}/doc/requirements.txt
 commands =


Reply via email to