diff options
35 files changed, 340 insertions, 426 deletions
diff --git a/doc/requirements.txt b/doc/requirements.txt index e8ba0fa..97c1879 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,7 +1,7 @@ # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -openstackdocstheme>=1.20.0 # Apache-2.0 -reno>=2.5.0 # Apache-2.0 -sphinx!=1.6.6,!=1.6.7,!=2.1.0,>=1.6.2 # BSD +openstackdocstheme>=2.2.1 # Apache-2.0 +reno>=3.1.0 # Apache-2.0 +sphinx>=2.0.0,!=2.1.0 # BSD sphinxcontrib-apidoc>=0.2.0 # BSD diff --git a/doc/source/conf.py b/doc/source/conf.py index 74d6595..bfe9b56 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -16,7 +16,6 @@ import os import sys -import openstackdocstheme sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) @@ -39,9 +38,9 @@ apidoc_excluded_paths = [ apidoc_separate_modules = True # openstackdocstheme options -repository_name = 'openstack/python-glanceclient' -bug_project = 'python-glanceclient' -bug_tag = '' +openstackdocs_repo_name = 'openstack/python-glanceclient' +openstackdocs_bug_project = 'python-glanceclient' +openstackdocs_bug_tag = '' # autodoc generation is a bit aggressive and a nuisance when doing heavy # text edit cycles. @@ -68,7 +67,7 @@ add_function_parentheses = True add_module_names = True # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = 'native' # -- Options for HTML output -------------------------------------------------- @@ -77,10 +76,6 @@ pygments_style = 'sphinx' #html_theme = 'nature' html_theme = 'openstackdocs' -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = ['_theme'] -html_theme_path = [openstackdocstheme.get_html_theme_path()] - # Output file base name for HTML help builder. htmlhelp_basename = '%sdoc' % project diff --git a/glanceclient/common/http.py b/glanceclient/common/http.py index 6973f60..e24ba35 100644 --- a/glanceclient/common/http.py +++ b/glanceclient/common/http.py @@ -14,6 +14,7 @@ # under the License. import copy +import io import logging import socket @@ -23,8 +24,7 @@ import OpenSSL from oslo_utils import importutils from oslo_utils import netutils import requests -import six -import six.moves.urllib.parse as urlparse +import urllib.parse try: import json @@ -66,19 +66,13 @@ def encode_headers(headers): for h, v in headers.items(): if v is not None: # if the item is token, do not quote '+' as well. - # NOTE(imacdonn): urlparse.quote() is intended for quoting the + # NOTE(imacdonn): urllib.parse.quote() is intended for quoting the # path part of a URL, but headers like x-image-meta-location # include an entire URL. We should avoid encoding the colon in # this case (bug #1788942) safe = '=+/' if h in TOKEN_HEADERS else '/:' - if six.PY2: - # incoming items may be unicode, so get them into something - # the py2 version of urllib can handle before percent encoding - key = urlparse.quote(encodeutils.safe_encode(h), safe) - value = urlparse.quote(encodeutils.safe_encode(v), safe) - else: - key = urlparse.quote(h, safe) - value = urlparse.quote(v, safe) + key = urllib.parse.quote(h, safe) + value = urllib.parse.quote(v, safe) encoded_dict[key] = value return dict((encodeutils.safe_encode(h, encoding='ascii'), encodeutils.safe_encode(v, encoding='ascii')) @@ -105,7 +99,7 @@ class _BaseHTTPClient(object): # NOTE(jamielennox): remove this later. Managers should pass json= if # they want to send json data. data = kwargs.pop("data", None) - if data is not None and not isinstance(data, six.string_types): + if data is not None and not isinstance(data, str): try: data = json.dumps(data) content_type = 'application/json' @@ -143,7 +137,7 @@ class _BaseHTTPClient(object): # response encoding body_iter = resp.json() else: - body_iter = six.StringIO(content) + body_iter = io.StringIO(content) try: body_iter = json.loads(''.join([c for c in body_iter])) except ValueError: @@ -209,13 +203,13 @@ class HTTPClient(_BaseHTTPClient): if not self.session.verify: curl.append('-k') else: - if isinstance(self.session.verify, six.string_types): + if isinstance(self.session.verify, str): curl.append(' --cacert %s' % self.session.verify) if self.session.cert: curl.append(' --cert %s --key %s' % self.session.cert) - if data and isinstance(data, six.string_types): + if data and isinstance(data, str): curl.append('-d \'%s\'' % data) curl.append(url) @@ -352,7 +346,6 @@ class SessionClient(adapter.Adapter, _BaseHTTPClient): def __init__(self, session, **kwargs): kwargs.setdefault('user_agent', USER_AGENT) kwargs.setdefault('service_type', 'image') - self.global_request_id = kwargs.pop('global_request_id', None) super(SessionClient, self).__init__(session, **kwargs) def request(self, url, method, **kwargs): diff --git a/glanceclient/common/https.py b/glanceclient/common/https.py index deb7eb0..94aeeb3 100644 --- a/glanceclient/common/https.py +++ b/glanceclient/common/https.py @@ -20,10 +20,6 @@ import struct import OpenSSL -import six -# NOTE(jokke): simplified transition to py3, behaves like py2 xrange -from six.moves import range - try: from eventlet import patcher # Handle case where we are running in a monkey patched environment @@ -33,9 +29,9 @@ try: else: raise ImportError except ImportError: + import http.client from OpenSSL import SSL - from six.moves import http_client - HTTPSConnection = http_client.HTTPSConnection + HTTPSConnection = http.client.HTTPSConnection Connection = SSL.Connection @@ -120,8 +116,8 @@ def host_matches_cert(host, x509): def to_bytes(s): - if isinstance(s, six.string_types): - return six.b(s) + if isinstance(s, str): + return bytes(s, 'latin-1') else: return s @@ -161,14 +157,7 @@ class VerifiedHTTPSConnection(HTTPSConnection): ssl_compression=True): # List of exceptions reported by Python3 instead of # SSLConfigurationError - if six.PY3: - excp_lst = (TypeError, FileNotFoundError, ssl.SSLError) - else: - # NOTE(jamespage) - # Accommodate changes in behaviour for pep-0467, introduced - # in python 2.7.9. - # https://github.com/python/peps/blob/master/pep-0476.txt - excp_lst = (TypeError, IOError, ssl.SSLError) + excp_lst = (TypeError, FileNotFoundError, ssl.SSLError) try: HTTPSConnection.__init__(self, host, port, key_file=key_file, diff --git a/glanceclient/common/progressbar.py b/glanceclient/common/progressbar.py index 6cf0df3..bb8b21b 100644 --- a/glanceclient/common/progressbar.py +++ b/glanceclient/common/progressbar.py @@ -15,8 +15,6 @@ import sys -import six - class _ProgressBarBase(object): """A progress bar provider for a wrapped obect. @@ -83,7 +81,7 @@ class VerboseIteratorWrapper(_ProgressBarBase): def next(self): try: - data = six.next(self._wrapped) + data = next(self._wrapped) # NOTE(mouad): Assuming that data is a string b/c otherwise calling # len function will not make any sense. self._display_progress_bar(len(data)) diff --git a/glanceclient/common/utils.py b/glanceclient/common/utils.py index 0fde763..4084e0e 100644 --- a/glanceclient/common/utils.py +++ b/glanceclient/common/utils.py @@ -13,20 +13,17 @@ # License for the specific language governing permissions and limitations # under the License. -from __future__ import print_function - import errno import functools import hashlib import json import os import re -import six.moves.urllib.parse as urlparse import sys import threading +import urllib.parse import uuid -import six if os.name == 'nt': # noqa import msvcrt # noqa @@ -161,7 +158,7 @@ def schema_args(schema_getter, omit=None): # for the `join` to succeed. Enum types can also be `None` # therefore, join's call would fail without the following # list comprehension - vals = [six.text_type(val) for val in property.get('enum')] + vals = [str(val) for val in property.get('enum')] description += ('Valid values: ' + ', '.join(vals)) kwargs['help'] = description @@ -216,8 +213,6 @@ def print_list(objs, fields, formatters=None, field_settings=None): def _encode(src): """remove extra 'u' in PY2.""" - if six.PY2 and isinstance(src, unicode): - return src.encode('utf-8') return src @@ -345,7 +340,7 @@ def get_file_size(file_obj): :retval: The file's size or None if it cannot be determined. """ if (hasattr(file_obj, 'seek') and hasattr(file_obj, 'tell') and - (six.PY2 or six.PY3 and file_obj.seekable())): + file_obj.seekable()): try: curr = file_obj.tell() file_obj.seek(0, os.SEEK_END) @@ -401,13 +396,13 @@ def strip_version(endpoint): # we make endpoint the first argument. However, we # can't do that just yet because we need to keep # backwards compatibility. - if not isinstance(endpoint, six.string_types): + if not isinstance(endpoint, str): raise ValueError("Expected endpoint") version = None # Get rid of trailing '/' if present endpoint = endpoint.rstrip('/') - url_parts = urlparse.urlparse(endpoint) + url_parts = urllib.parse.urlparse(endpoint) (scheme, netloc, path, __, __, __) = url_parts path = path.lstrip('/') # regex to match 'v1' or 'v2.0' etc @@ -446,8 +441,8 @@ def integrity_iter(iter, checksum): for chunk in iter: yield chunk - if isinstance(chunk, six.string_types): - chunk = six.b(chunk) + if isinstance(chunk, str): + chunk = bytes(chunk, 'latin-1') md5sum.update(chunk) md5sum = md5sum.hexdigest() if md5sum != checksum: @@ -466,8 +461,8 @@ def serious_integrity_iter(iter, hasher, hash_value): """ for chunk in iter: yield chunk - if isinstance(chunk, six.string_types): - chunk = six.b(chunk) + if isinstance(chunk, str): + chunk = bytes(chunk, 'latin-1') hasher.update(chunk) computed = hasher.hexdigest() if computed != hash_value: diff --git a/glanceclient/exc.py b/glanceclient/exc.py index eee47ca..5efe805 100644 --- a/glanceclient/exc.py +++ b/glanceclient/exc.py @@ -16,8 +16,6 @@ import re import sys -import six - class BaseException(Exception): """An error occurred.""" @@ -179,8 +177,7 @@ def from_response(response, body=None): details = ': '.join(details_temp) return cls(details=details) elif body: - if six.PY3: - body = body.decode('utf-8') + body = body.decode('utf-8') details = body.replace('\n\n', '\n') return cls(details=details) diff --git a/glanceclient/shell.py b/glanceclient/shell.py index 3dfa14a..ca10359 100644 --- a/glanceclient/shell.py +++ b/glanceclient/shell.py @@ -17,8 +17,6 @@ Command-line interface to the OpenStack Images API. """ -from __future__ import print_function - import argparse import copy import getpass @@ -31,8 +29,7 @@ import traceback from oslo_utils import encodeutils from oslo_utils import importutils -import six -import six.moves.urllib.parse as urlparse +import urllib.parse import glanceclient from glanceclient._i18n import _ @@ -259,7 +256,7 @@ class OpenStackImagesShell(object): except ks_exc.ClientException as e: # Identity service may not support discover API version. # Lets trying to figure out the API version from the original URL. - url_parts = urlparse.urlparse(auth_url) + url_parts = urllib.parse.urlparse(auth_url) (scheme, netloc, path, params, query, fragment) = url_parts path = path.lower() if path.startswith('/v3'): @@ -522,12 +519,6 @@ class OpenStackImagesShell(object): self.do_help(options, parser=parser) return 0 - # NOTE(sigmavirus24): Above, args is defined as the left over - # arguments from parser.parse_known_args(). This allows us to - # skip any parameters to command-line flags that may have been passed - # to glanceclient, e.g., --os-auth-token. - self._fixup_subcommand(args, argv) - # short-circuit and deal with help command right away. sub_parser = _get_subparser(api_version) args = sub_parser.parse_args(argv) @@ -598,33 +589,6 @@ class OpenStackImagesShell(object): print("To display trace use next command:\n" "osprofiler trace show --html %s " % trace_id) - @staticmethod - def _fixup_subcommand(unknown_args, argv): - # NOTE(sigmavirus24): Sometimes users pass the wrong subcommand name - # to glanceclient. If they're using Python 2 they will see an error: - # > invalid choice: u'imgae-list' (choose from ...) - # To avoid this, we look at the extra args already parsed from above - # and try to predict what the subcommand will be based on it being the - # first non - or -- prefixed argument in args. We then find that in - # argv and encode it from unicode so users don't see the pesky `u'` - # prefix. - for arg in unknown_args: - if not arg.startswith('-'): # This will cover both - and -- - subcommand_name = arg - break - else: - subcommand_name = '' - - if (subcommand_name and six.PY2 and - isinstance(subcommand_name, six.text_type)): - # NOTE(sigmavirus24): if we found a subcommand name, then let's - # find it in the argv list and replace it with a bytes object - # instead. Note, that if we encode the argument on Python 3, the - # user will instead see a pesky `b'` string instead of the `u'` - # string we mention above. - subcommand_index = argv.index(subcommand_name) - argv[subcommand_index] = encodeutils.safe_encode(subcommand_name) - @utils.arg('command', metavar='<subcommand>', nargs='?', help='Display help for <subcommand>.') def do_help(self, args, parser): diff --git a/glanceclient/tests/unit/test_http.py b/glanceclient/tests/unit/test_http.py index 0cf8f5b..5759ccd 100644 --- a/glanceclient/tests/unit/test_http.py +++ b/glanceclient/tests/unit/test_http.py @@ -19,13 +19,13 @@ from unittest import mock import uuid import fixtures +import io from keystoneauth1 import session from keystoneauth1 import token_endpoint from oslo_utils import encodeutils import requests from requests_mock.contrib import fixture -import six -from six.moves.urllib import parse +from urllib import parse from testscenarios import load_tests_apply_scenarios as load_tests # noqa import testtools from testtools import matchers @@ -267,6 +267,20 @@ class TestClient(testtools.TestCase): self.assertEqual(b"application/openstack-images-v2.1-json-patch", ksarqh[b"Content-Type"]) + def test_request_id_header_session_client(self): + global_id = "req-%s" % uuid.uuid4() + kwargs = {'global_request_id': global_id} + auth = token_endpoint.Token(self.endpoint, self.token) + sess = session.Session(auth=auth) + http_client = http.SessionClient(sess, **kwargs) + + path = '/v2/images/my-image' + self.mock.get(self.endpoint + path) + http_client.get(path) + + headers = self.mock.last_request.headers + self.assertEqual(global_id, headers['X-OpenStack-Request-ID']) + def test_raw_request(self): """Verify the path being used for HTTP requests reflects accurately.""" headers = {"Content-Type": "text/plain"} @@ -296,14 +310,14 @@ class TestClient(testtools.TestCase): def test__chunk_body_exact_size_chunk(self): test_client = http._BaseHTTPClient() bytestring = b'x' * http.CHUNKSIZE - data = six.BytesIO(bytestring) + data = io.BytesIO(bytestring) chunk = list(test_client._chunk_body(data)) self.assertEqual(1, len(chunk)) self.assertEqual([bytestring], chunk) def test_http_chunked_request(self): text = "Ok" - data = six.StringIO(text) + data = io.StringIO(text) path = '/v1/images/' self.mock.post(self.endpoint + path, text=text) @@ -322,13 +336,13 @@ class TestClient(testtools.TestCase): resp, body = self.client.post(path, headers=headers, data=data) self.assertEqual(text, resp.text) - self.assertIsInstance(self.mock.last_request.body, six.string_types) + self.assertIsInstance(self.mock.last_request.body, str) self.assertEqual(data, json.loads(self.mock.last_request.body)) def test_http_chunked_response(self): data = "TEST" path = '/v1/images/' - self.mock.get(self.endpoint + path, body=six.StringIO(data), + self.mock.get(self.endpoint + path, body=io.StringIO(data), headers={"Content-Type": "application/octet-stream"}) resp, body = self.client.get(path) @@ -341,7 +355,7 @@ class TestClient(testtools.TestCase): response = 'Ok' headers = {"Content-Type": "text/plain", "test": "value1\xa5\xa6"} - fake = utils.FakeResponse(headers, six.StringIO(response)) + fake = utils.FakeResponse(headers, io.StringIO(response)) self.client.log_http_response(fake) except UnicodeDecodeError as e: self.fail("Unexpected UnicodeDecodeError exception '%s'" % e) @@ -444,7 +458,7 @@ class TestClient(testtools.TestCase): logger = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) data = "TEST" path = '/v1/images/' - self.mock.get(self.endpoint + path, body=six.StringIO(data), + self.mock.get(self.endpoint + path, body=io.StringIO(data), headers={"Content-Type": "application/octet-stream", 'x-openstack-request-id': "1234"}) diff --git a/glanceclient/tests/unit/test_progressbar.py b/glanceclient/tests/unit/test_progressbar.py index 76f96fb..d0596d5 100644 --- a/glanceclient/tests/unit/test_progressbar.py +++ b/glanceclient/tests/unit/test_progressbar.py @@ -13,10 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +import io import sys import requests -import six import testtools from glanceclient.common import progressbar @@ -49,7 +49,7 @@ class TestProgressBarWrapper(testtools.TestCase): def test_iter_file_display_progress_bar(self): size = 98304 - file_obj = six.StringIO('X' * size) + file_obj = io.StringIO('X' * size) saved_stdout = sys.stdout try: sys.stdout = output = test_utils.FakeTTYStdout() @@ -67,7 +67,7 @@ class TestProgressBarWrapper(testtools.TestCase): def test_iter_file_no_tty(self): size = 98304 - file_obj = six.StringIO('X' * size) + file_obj = io.StringIO('X' * size) saved_stdout = sys.stdout try: sys.stdout = output = test_utils.FakeNoTTYStdout() diff --git a/glanceclient/tests/unit/test_shell.py b/glanceclient/tests/unit/test_shell.py index b23591f..74d1c33 100644 --- a/glanceclient/tests/unit/test_shell.py +++ b/glanceclient/tests/unit/test_shell.py @@ -17,6 +17,7 @@ import argparse from collections import OrderedDict import hashlib +import io import logging import os import sys @@ -28,7 +29,6 @@ import fixtures from keystoneauth1 import exceptions as ks_exc from keystoneauth1 import fixture as ks_fixture from requests_mock.contrib import fixture as rm_fixture -import six from glanceclient.common import utils from glanceclient import exc @@ -144,8 +144,8 @@ class ShellTest(testutils.TestCase): orig = sys.stdout orig_stderr = sys.stderr try: - sys.stdout = six.StringIO() - sys.stderr = six.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() _shell = openstack_shell.OpenStackImagesShell() _shell.main(argstr.split()) except SystemExit: @@ -160,42 +160,13 @@ class ShellTest(testutils.TestCase): sys.stderr = orig_stderr return (stdout, stderr) - def test_fixup_subcommand(self): - arglist = [u'image-list', u'--help'] - if six.PY2: - expected_arglist = [b'image-list', u'--help'] - elif six.PY3: - expected_arglist = [u'image-list', u'--help'] - - openstack_shell.OpenStackImagesShell._fixup_subcommand( - arglist, arglist - ) - self.assertEqual(expected_arglist, arglist) - - def test_fixup_subcommand_with_options_preceding(self): - arglist = [u'--os-auth-token', u'abcdef', u'image-list', u'--help'] - unknown = arglist[2:] - if six.PY2: - expected_arglist = [ - u'--os-auth-token', u'abcdef', b'image-list', u'--help' - ] - elif six.PY3: - expected_arglist = [ - u'--os-auth-token', u'abcdef', u'image-list', u'--help' - ] - - openstack_shell.OpenStackImagesShell._fixup_subcommand( - unknown, arglist - ) - self.assertEqual(expected_arglist, arglist) - def test_help_unknown_command(self): shell = openstack_shell.OpenStackImagesShell() argstr = '--os-image-api-version 2 help foofoo' self.assertRaises(exc.CommandError, shell.main, argstr.split()) - @mock.patch('sys.stdout', six.StringIO()) - @mock.patch('sys.stderr', six.StringIO()) + @mock.patch('sys.stdout', io.StringIO()) + @mock.patch('sys.stderr', io.StringIO()) @mock.patch('sys.argv', ['glance', 'help', 'foofoo']) def test_no_stacktrace_when_debug_disabled(self): with mock.patch.object(traceback, 'print_exc') as mock_print_exc: @@ -205,8 +176,8 @@ class ShellTest(testutils.TestCase): pass self.assertFalse(mock_print_exc.called) - @mock.patch('sys.stdout', six.StringIO()) - @mock.patch('sys.stderr', six.StringIO()) + @mock.patch('sys.stdout', io.StringIO()) + @mock.patch('sys.stderr', io.StringIO()) @mock.patch('sys.argv', ['glance', 'help', 'foofoo']) def test_stacktrace_when_debug_enabled_by_env(self): old_environment = os.environ.copy() @@ -221,8 +192,8 @@ class ShellTest(testutils.TestCase): finally: os.environ = old_environment - @mock.patch('sys.stdout', six.StringIO()) - @mock.patch('sys.stderr', six.StringIO()) + @mock.patch('sys.stdout', io.StringIO()) + @mock.patch('sys.stderr', io.StringIO()) @mock.patch('sys.argv', ['glance', '--debug', 'help', 'foofoo']) def test_stacktrace_when_debug_enabled(self): with mock.patch.object(traceback, 'print_exc') as mock_print_exc: @@ -589,8 +560,8 @@ class ShellTest(testutils.TestCase): self.assertRaises(exc.CommandError, glance_shell.main, args.split()) @mock.patch('sys.argv', ['glance']) - @mock.patch('sys.stdout', six.StringIO()) - @mock.patch('sys.stderr', six.StringIO()) + @mock.patch('sys.stdout', io.StringIO()) + @mock.patch('sys.stderr', io.StringIO()) def test_main_noargs(self): # Ensure that main works with no command-line arguments try: @@ -781,7 +752,7 @@ class ShellCacheSchemaTest(testutils.TestCase): return Args(args) - @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True) + @mock.patch('builtins.open', new=mock.mock_open(), create=True) @mock.patch('os.path.exists', return_value=True) def test_cache_schemas_gets_when_forced(self, exists_mock): options = { @@ -804,7 +775,7 @@ class ShellCacheSchemaTest(testutils.TestCase): actual = json.loads(open.mock_calls[6][1][0]) self.assertEqual(schema_odict, actual) - @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True) + @mock.patch('builtins.open', new=mock.mock_open(), create=True) @mock.patch('os.path.exists', side_effect=[True, False, False, False]) def test_cache_schemas_gets_when_not_exists(self, exists_mock): options = { @@ -827,7 +798,7 @@ class ShellCacheSchemaTest(testutils.TestCase): actual = json.loads(open.mock_calls[6][1][0]) self.assertEqual(schema_odict, actual) - @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True) + @mock.patch('builtins.open', new=mock.mock_open(), create=True) @mock.patch('os.path.exists', return_value=True) def test_cache_schemas_leaves_when_present_not_forced(self, exists_mock): options = { @@ -848,7 +819,7 @@ class ShellCacheSchemaTest(testutils.TestCase): self.assertEqual(4, exists_mock.call_count) self.assertEqual(0, open.mock_calls.__len__()) - @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True) + @mock.patch('builtins.open', new=mock.mock_open(), create=True) @mock.patch('os.path.exists', return_value=True) def test_cache_schemas_leaves_auto_switch(self, exists_mock): options = { @@ -899,7 +870,7 @@ class ShellTestRequests(testutils.TestCase): headers = {'Content-Length': '4', 'Content-type': 'application/octet-stream'} - fake = testutils.FakeResponse(headers, six.StringIO('DATA')) + fake = testutils.FakeResponse(headers, io.StringIO('DATA')) self.requests.get('http://example.com/v1/images/%s' % id, raw=fake) @@ -938,7 +909,7 @@ class ShellTestRequests(testutils.TestCase): headers = {'Content-Length': '4', 'Content-type': 'application/octet-stream'} - fake = testutils.FakeResponse(headers, six.StringIO('DATA')) + fake = testutils.FakeResponse(headers, io.StringIO('DATA')) self.requests.get('http://example.com/v1/images/%s' % id, headers=headers, raw=fake) @@ -960,7 +931,7 @@ class ShellTestRequests(testutils.TestCase): id = image_show_fixture['id'] headers = {'Content-Length': '4', 'Content-type': 'application/octet-stream'} - fake = testutils.FakeResponse(headers, six.StringIO('DATA')) + fake = testutils.FakeResponse(headers, io.StringIO('DATA')) self.requests = self.useFixture(rm_fixture.Fixture()) self.requests.get('http://example.com/v2/images/%s/file' % id, diff --git a/glanceclient/tests/unit/test_ssl.py b/glanceclient/tests/unit/test_ssl.py index 320dfde..f95e777 100644 --- a/glanceclient/tests/unit/test_ssl.py +++ b/glanceclient/tests/unit/test_ssl.py @@ -16,7 +16,6 @@ import os from unittest import mock -import six import ssl import testtools import threading @@ -26,10 +25,7 @@ from glanceclient import exc from glanceclient import v1 from glanceclient import v2 -if six.PY3 is True: - import socketserver -else: - import SocketServer as socketserver +import socketserver TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), @@ -217,9 +213,7 @@ class TestHTTPSVerifyCert(testtools.TestCase): # starting from python 2.7.8 the way to handle loading private # keys into the SSL_CTX was changed and error message become # similar to the one in 3.X - if (six.PY2 and 'PrivateKey' not in e.message and - 'PEM lib' not in e.message or - six.PY3 and 'PEM lib' not in e.message): + if 'PEM lib' not in e.message: self.fail('No appropriate failure message is received') @mock.patch('sys.stderr') diff --git a/glanceclient/tests/unit/test_utils.py b/glanceclient/tests/unit/test_utils.py index 6128d6c..46cefbf 100644 --- a/glanceclient/tests/unit/test_utils.py +++ b/glanceclient/tests/unit/test_utils.py @@ -13,14 +13,13 @@ # License for the specific language governing permissions and limitations # under the License. +import io import sys from unittest import mock from oslo_utils import encodeutils from requests import Response -import six # NOTE(jokke): simplified transition to py3, behaves like py2 xrange -from six.moves import range import testtools from glanceclient.common import utils @@ -47,7 +46,7 @@ class TestUtils(testtools.TestCase): def test_get_new_file_size(self): size = 98304 - file_obj = six.StringIO('X' * size) + file_obj = io.StringIO('X' * size) try: self.assertEqual(size, utils.get_file_size(file_obj)) # Check that get_file_size didn't change original file position. @@ -57,7 +56,7 @@ class TestUtils(testtools.TestCase): def test_get_consumed_file_size(self): size, consumed = 98304, 304 - file_obj = six.StringIO('X' * size) + file_obj = io.StringIO('X' * size) file_obj.seek(consumed) try: self.assertEqual(size, utils.get_file_size(file_obj)) @@ -79,10 +78,10 @@ class TestUtils(testtools.TestCase): saved_stdout = sys.stdout try: - sys.stdout = output_list = six.StringIO() + sys.stdout = output_list = io.StringIO() utils.print_list(images, columns) - sys.stdout = output_dict = six.StringIO() + sys.stdout = output_dict = io.StringIO() utils.print_dict({'K': 'k', 'Key': 'veeeeeeeeeeeeeeeeeeeeeeee' 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' @@ -126,7 +125,7 @@ class TestUtils(testtools.TestCase): 'tags': [u'Name1', u'Tag_123', u'veeeery long']})] saved_stdout = sys.stdout try: - sys.stdout = output_list = six.StringIO() + sys.stdout = output_list = io.StringIO() utils.print_list(images, columns) finally: @@ -145,7 +144,7 @@ class TestUtils(testtools.TestCase): image = {'id': '42', 'virtual_size': 1337} saved_stdout = sys.stdout try: - sys.stdout = output_list = six.StringIO() + sys.stdout = output_list = io.StringIO() utils.print_image(image) finally: sys.stdout = saved_stdout @@ -164,7 +163,7 @@ class TestUtils(testtools.TestCase): image = {'id': '42', 'virtual_size': None} saved_stdout = sys.stdout try: - sys.stdout = output_list = six.StringIO() + sys.stdout = output_list = io.StringIO() utils.print_image(image) finally: sys.stdout = saved_stdout @@ -181,13 +180,9 @@ class TestUtils(testtools.TestCase): def test_unicode_key_value_to_string(self): src = {u'key': u'\u70fd\u7231\u5a77'} - expected = {'key': '\xe7\x83\xbd\xe7\x88\xb1\xe5\xa9\xb7'} - if six.PY2: - self.assertEqual(expected, utils.unicode_key_value_to_string(src)) - else: - # u'xxxx' in PY3 is str, we will not get extra 'u' from cli - # output in PY3 - self.assertEqual(src, utils.unicode_key_value_to_string(src)) + # u'xxxx' in PY3 is str, we will not get extra 'u' from cli + # output in PY3 + self.assertEqual(src, utils.unicode_key_value_to_string(src)) def test_schema_args_with_list_types(self): # NOTE(flaper87): Regression for bug @@ -240,7 +235,7 @@ class TestUtils(testtools.TestCase): for chunk in i: raise(IOError) - data = six.moves.StringIO('somestring') + data = io.StringIO('somestring') data.close = mock.Mock() i = utils.IterableWithLength(data, 10) self.assertRaises(IOError, _iterate, i) diff --git a/glanceclient/tests/unit/v1/test_images.py b/glanceclient/tests/unit/v1/test_images.py index 1f43b83..1af7412 100644 --- a/glanceclient/tests/unit/v1/test_images.py +++ b/glanceclient/tests/unit/v1/test_images.py @@ -14,11 +14,10 @@ # under the License. import errno +import io import json import testtools - -import six -from six.moves.urllib import parse +from urllib import parse from glanceclient.tests import utils from glanceclient.v1 import client @@ -634,7 +633,7 @@ class ImageManagerTest(testtools.TestCase): self.assertEqual({'a': 'b', 'c': 'd'}, image.properties) def test_create_with_data(self): - image_data = six.StringIO('XXX') + image_data = io.StringIO('XXX') self.mgr.create(data=image_data) expect_headers = {'x-image-meta-size': '3'} expect = [('POST', '/v1/images', expect_headers, image_data)] @@ -711,7 +710,7 @@ class ImageManagerTest(testtools.TestCase): self.assertEqual(10, image.min_disk) def test_update_with_data(self): - image_data = six.StringIO('XXX') + image_data = io.StringIO('XXX') self.mgr.update('1', data=image_data) expect_headers = {'x-image-meta-size': '3', 'x-glance-registry-purge-props': 'false'} @@ -744,10 +743,7 @@ class ImageManagerTest(testtools.TestCase): def test_image_meta_from_headers_encoding(self): value = u"ni\xf1o" - if six.PY2: - fields = {"x-image-meta-name": "ni\xc3\xb1o"} - else: - fields = {"x-image-meta-name": value} + fields = {"x-image-meta-name": value} headers = self.mgr._image_meta_from_headers(fields) self.assertEqual(value, headers["name"]) diff --git a/glanceclient/tests/unit/v1/test_shell.py b/glanceclient/tests/unit/v1/test_shell.py index 5476a2f..46c6f68 100644 --- a/glanceclient/tests/unit/v1/test_shell.py +++ b/glanceclient/tests/unit/v1/test_shell.py @@ -15,11 +15,11 @@ # under the License. import argparse +import io import json import os from unittest import mock -import six import subprocess import tempfile import testtools @@ -34,12 +34,6 @@ import glanceclient.v1.shell as v1shell from glanceclient.tests import utils -if six.PY3: - import io - file_type = io.IOBase -else: - file_type = file - fixtures = { '/v1/images/96d2c7e1-de4e-4612-8aa2-ba26610c804e': { 'PUT': ( @@ -351,7 +345,7 @@ class ShellInvalidEndpointandParameterTest(utils.TestCase): @mock.patch('sys.stderr') def test_image_create_missing_container_format_stdin_data(self, __): # Fake that get_data_file method returns data - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() e = self.assertRaises(exc.CommandError, self.run_command, '--os-image-api-version 1 image-create' ' --disk-format qcow2') @@ -361,7 +355,7 @@ class ShellInvalidEndpointandParameterTest(utils.TestCase): @mock.patch('sys.stderr') def test_image_create_missing_disk_format_stdin_data(self, __): # Fake that get_data_file method returns data - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() e = self.assertRaises(exc.CommandError, self.run_command, '--os-image-api-version 1 image-create' ' --container-format bare') @@ -574,7 +568,7 @@ class ShellStdinHandlingTests(testtools.TestCase): self._do_update('44d2c7e1-de4e-4612-8aa2-ba26610c444f') self.assertIn('data', self.collected_args[1]) - self.assertIsInstance(self.collected_args[1]['data'], file_type) + self.assertIsInstance(self.collected_args[1]['data'], io.IOBase) self.assertEqual(b'Some Data', self.collected_args[1]['data'].read()) @@ -599,7 +593,7 @@ class ShellStdinHandlingTests(testtools.TestCase): self._do_update('44d2c7e1-de4e-4612-8aa2-ba26610c444f') self.assertIn('data', self.collected_args[1]) - self.assertIsInstance(self.collected_args[1]['data'], file_type) + self.assertIsInstance(self.collected_args[1]['data'], io.IOBase) self.assertEqual(b'Some Data\n', self.collected_args[1]['data'].read()) diff --git a/glanceclient/tests/unit/v2/test_shell_v2.py b/glanceclient/tests/unit/v2/test_shell_v2.py index 9c19551..3f1d77a 100644 --- a/glanceclient/tests/unit/v2/test_shell_v2.py +++ b/glanceclient/tests/unit/v2/test_shell_v2.py @@ -15,11 +15,11 @@ # under the License. import argparse from copy import deepcopy +import io import json import os from unittest import mock -import six import sys import tempfile import testtools @@ -196,7 +196,7 @@ class ShellV2Test(testtools.TestCase): @mock.patch('sys.stderr') def test_image_create_missing_container_format_stdin_data(self, __): # Fake that get_data_file method returns data - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() e = self.assertRaises(exc.CommandError, self._run_command, '--os-image-api-version 2 image-create' ' --disk-format qcow2') @@ -206,7 +206,7 @@ class ShellV2Test(testtools.TestCase): @mock.patch('sys.stderr') def test_image_create_missing_disk_format_stdin_data(self, __): # Fake that get_data_file method returns data - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() e = self.assertRaises(exc.CommandError, self._run_command, '--os-image-api-version 2 image-create' ' --container-format bare') @@ -618,7 +618,7 @@ class ShellV2Test(testtools.TestCase): 'os_hash_value': None}) def test_do_image_create_with_multihash(self): - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() try: with open(tempfile.mktemp(), 'w+') as f: f.write('Some data here') @@ -694,7 +694,7 @@ class ShellV2Test(testtools.TestCase): 'container_format': 'bare', 'os_hidden': True}) def test_do_image_create_with_file(self): - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() try: file_name = None with open(tempfile.mktemp(), 'w+') as f: @@ -1412,7 +1412,7 @@ class ShellV2Test(testtools.TestCase): self, mock_stdin, mock_do_stage, mock_do_import): """Backward compat -> handle this like a glance-direct""" mock_stdin.isatty = lambda: False - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() args = self._make_args(self.base_args) with mock.patch.object(self.gc.images, 'create') as mocked_create: with mock.patch.object(self.gc.images, 'get') as mocked_get: @@ -1447,7 +1447,7 @@ class ShellV2Test(testtools.TestCase): self, mock_stdin, mock_access, mock_do_stage, mock_do_import): """Backward compat -> handle this like a glance-direct""" mock_stdin.isatty = lambda: True - self.mock_get_data_file.return_value = six.StringIO() + self.mock_get_data_file.return_value = io.StringIO() mock_access.return_value = True my_args = self.base_args.copy() my_args['file'] = 'fake-image-file.browncow' @@ -1557,6 +1557,56 @@ class ShellV2Test(testtools.TestCase): 'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd', 'container_format': 'bare', 'status': 'queued'}) + @mock.patch('glanceclient.v2.shell.do_image_import') + @mock.patch('glanceclient.v2.shell.do_image_stage') + @mock.patch('sys.stdin', autospec=True) + def test_do_image_create_via_import_with_web_download_with_stores( + self, mock_stdin, mock_do_image_stage, mock_do_image_import): + temp_args = {'name': 'IMG-01', + 'disk_format': 'vhd', + 'container_format': 'bare', + 'uri': 'http://example.com/image.qcow', + 'import_method': 'web-download', + 'progress': False, + 'stores': 'file1,file2'} + tmp2_args = {'name': 'IMG-01', + 'disk_format': 'vhd', + 'container_format': 'bare', + 'uri': 'http://example.com/image.qcow', + 'import_method': 'web-download', + 'progress': False} + args = self._make_args(temp_args) + with mock.patch.object(self.gc.images, 'create') as mocked_create: + with mock.patch.object(self.gc.images, 'get') as mocked_get: + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + with mock.patch.object(self.gc.images, + 'get_stores_info') as m_stores_info: + + ignore_fields = ['self', 'access', 'schema'] + expect_image = dict([(field, field) for field in + ignore_fields]) + expect_image['id'] = 'pass' + expect_image['name'] = 'IMG-01' + expect_image['disk_format'] = 'vhd' + expect_image['container_format'] = 'bare' + expect_image['status'] = 'queued' + mocked_create.return_value = expect_image + mocked_get.return_value = expect_image + mocked_info.return_value = self.import_info_response + m_stores_info.return_value = self.stores_info_response + mock_stdin.isatty = lambda: True + + test_shell.do_image_create_via_import(self.gc, args) + mock_do_image_stage.assert_not_called() + mock_do_image_import.assert_called_once() + mocked_create.assert_called_once_with(**tmp2_args) + mocked_get.assert_called_with('pass') + utils.print_dict.assert_called_with({ + 'id': 'pass', 'name': 'IMG-01', + 'disk_format': 'vhd', + 'container_format': 'bare', 'status': 'queued'}) + def test_do_image_update_no_user_props(self): args = self._make_args({'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd', diff --git a/glanceclient/tests/unit/var/ca.crt b/glanceclient/tests/unit/var/ca.crt index c149d8c..cfdda79 100644 --- a/glanceclient/tests/unit/var/ca.crt +++ b/glanceclient/tests/unit/var/ca.crt @@ -1,34 +1,36 @@ -----BEGIN CERTIFICATE----- -MIIF7jCCA9YCCQDbl9qx7iIeJDANBgkqhkiG9w0BAQUFADCBuDEZMBcGA1UEChMQ -T3BlbnN0YWNrIENBIE9yZzEaMBgGA1UECxMRT3BlbnN0YWNrIFRlc3QgQ0ExIzAh -BgkqhkiG9w0BCQEWFGFkbWluQGNhLmV4YW1wbGUuY29tMREwDwYDVQQHEwhTdGF0 -ZSBDQTELMAkGA1UECBMCQ0ExCzAJBgNVBAYTAkFVMS0wKwYDVQQDEyRPcGVuc3Rh -Y2sgVGVzdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTIxMTE2MTI1MDE2WhcN -NDAwNDAzMTI1MDE2WjCBuDEZMBcGA1UEChMQT3BlbnN0YWNrIENBIE9yZzEaMBgG -A1UECxMRT3BlbnN0YWNrIFRlc3QgQ0ExIzAhBgkqhkiG9w0BCQEWFGFkbWluQGNh -LmV4YW1wbGUuY29tMREwDwYDVQQHEwhTdGF0ZSBDQTELMAkGA1UECBMCQ0ExCzAJ -BgNVBAYTAkFVMS0wKwYDVQQDEyRPcGVuc3RhY2sgVGVzdCBDZXJ0aWZpY2F0ZSBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC94cpBjwj2 -MD0w5j1Jlcy8Ljmk3r7CRaoV5vhWUrAWpT7Thxr/Ti0qAfZZRSIVpvBM0RlseH0Q -toUJixuYMoNRPUQ74r/TRoO8HfjQDJfnXtWg2L7DRP8p4Zgj3vByBUCU+rKsbI/H -Nssl/AronADbZXCoL5hJRN8euMYZGrt/Gh1ZotKE5gQlEjylDFlA3s3pn+ABLgzf -7L7iufwV3zLdPRHCb6Ve8YvUmKfI6gy+WwTRhNhLz4Nj0uBthnj6QhnRXtxkNT7A -aAStqKH6TtYRnk2Owh8ITFbtLQ0/MSV8jHAxMXx9AloBhEKxv3cIpgLH6lOCnj// -Ql+H6/QWtmTUHzP1kBfMhTQnWTfR92QTcgEMiZ7a07VyVtLh+kp/G5IUqpM6Pyz/ -O6QDs7FF69bTpws7Ce916PPrGFZ9Gqvo/P0jXge8kYqO+a8QnTRldAxdUzPJCK9+ -Dyi2LWeHf8nPFYdwW9Ov6Jw1CKDYxjJg6KIwnrMPa2eUdPB6/OKkqr9/KemOoKQu -4KSaYadFZbaJwt7JPZaHy6TpkGxW7Af8RqGrW6a6nWEFcfO2POuHcAHWL5LiRmni -unm60DBF3b3itDTqCvER3mZE9pN8dqtxdpB8SUX8eq0UJJK2K8mJQS+oE9crbqYb -1kQbYjhhPLlvOQru+/m/abqZrC04u2OtYQIDAQABMA0GCSqGSIb3DQEBBQUAA4IC -AQA8wGVBbzfpQ3eYpchiHyHF9N5LIhr6Bt4jYDKLz8DIbElLtoOlgH/v7hLGJ7wu -R9OteonwQ1qr9umMmnp61bKXOEBJLBJbGKEt0MNLmmX89+M/h3rdMVZEz/Hht/xK -Xm4di8pjkHfmdhqsbiFW81lAt9W1r74lnH7wQHr9ueALGKDx0hi8pAZ27itgQVHL -eA1erhw0kjr9BqWpDIskVwePcD7pFoZ48GQlST0uIEq5U+1AWq7AbOABsqODygKi -Ri5pmTasNFT7nEX3ti4VN214MNy0JnPzTRNWR2rD0I30AebM3KkzTprbLVfnGkm4 -7hOPV+Wc8EjgbbrUAIp2YpOfO/9nbgljTOUsqfjqxzvHx/09XOo2M6NIE5UiHqIq -TXN7CeGIhBoYbvBAH2QvtveFXv41IYL4zFFXo4wTBSzCCOUGeDDv0U4hhsNaCkDQ -G2TcubNA4g/FAtqLvPj/6VbIIgFE/1/6acsT+W0O+kkVAb7ej2dpI7J+jKXDXuiA -PDCMn9dVQ7oAcaQvVdvvRphLdIZ9wHgqKhxKsMwzIMExuDKL0lWe/3sueFyol6nv -xRCSgzr5MqSObbO3EnWgcUocBvlPyYLnTM2T8C5wh3BGnJXqJSRETggNn8PXBVIm -+c5o+Ic0mYu4v8P1ZSozFdgf+HLriVPwzJU5dHvvTEu7sw== +MIIGVTCCBD2gAwIBAgIUEstxpjoCFDZo8K1Mmz7QIpYwSXIwDQYJKoZIhvcNAQEL +BQAwgbgxCzAJBgNVBAYTAkFVMREwDwYDVQQIDAhTdGF0ZSBDQTELMAkGA1UEBwwC +Q0ExGTAXBgNVBAoMEE9wZW5TdGFjayBDQSBPcmcxGjAYBgNVBAsMEU9wZW5TdGFj +ayBUZXN0IENBMS0wKwYDVQQDDCRPcGVuc3RhY2sgVGVzdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkxIzAhBgkqhkiG9w0BCQEWFGFkbWluQGNhLmV4YW1wbGUuY29tMCAX +DTIwMDQwNzEyMjYwMVoYDzI5OTkwMTAxMTIyNjAxWjCBuDELMAkGA1UEBhMCQVUx +ETAPBgNVBAgMCFN0YXRlIENBMQswCQYDVQQHDAJDQTEZMBcGA1UECgwQT3BlblN0 +YWNrIENBIE9yZzEaMBgGA1UECwwRT3BlblN0YWNrIFRlc3QgQ0ExLTArBgNVBAMM +JE9wZW5zdGFjayBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTEjMCEGCSqGSIb3 +DQEJARYUYWRtaW5AY2EuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQD6KfGpVSJsmhTgdbdovaaa3Qe4PeP+Dg9Y7muSggVQVlqUp3YB +xUSo1RDoLyu1ci+KrNODr+kkD/Cbo8yJQCxqTzUpCw3tadFhUJOWvPaqdcYTA8R9 +p7Xjvw3Me7Q7xr4l0pCUIiz/kwxYxk+GCQyXzpXZm14zz+Qm8gz37eoW2jJfoyzA +dB9Tp609Id7C6VHFCWZ2Zsa4+Ua/q+Pn7vLNJ61C2H5sfus8dtcGDzViDWwnWyHw +spyR79rciV2yA3xeq09RvIx2SB1tc3S2Rxw7SmKeYcnkv6YplvhIG5QpErvp+URh +De2wbbxzjFzJqFQO0Yh8IgTBIvQI02++lA8ZX84UDaxmrT92m8GfqQvb96em/H1k +RKJTq0QqSC+BbGDeFxHkuOTJiOZm5Bnivpo0TAPwX6YqpadXARAFWw+fJiHCuFGr +6ltD7zgRnx6SR5WNRNWmTZQNx7wC2Bm0cJ2ec0Asn+bl93RVloaNtbFJhkaN555G +GnUDLvxiwIN7aMGviJLte/qIhkKTtxD7zxyk+PQhokPAiz8J9P8INDd3GzMvcRPX +ufDoXjSGjSLzjVPMhkFxXaHHylBdEAtHxROKz5wJnHqCnKlyyyv0nGBPQxFjT+rb +G0HFn1JjodPBLrwooPttDgkEnq5yBpDkhFuYdZbgwjvQ4p5qrCp3EbDJ/QIDAQAB +o1MwUTAdBgNVHQ4EFgQUkfKdH+sf7F/69HDbvtZ/ggVDCt4wHwYDVR0jBBgwFoAU +kfKdH+sf7F/69HDbvtZ/ggVDCt4wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B +AQsFAAOCAgEAsUIwMa+2lR2a77AaVDDJikt4twylxJudJ4WEerFWOJeshCUCEGZF +udlkLDMl9/f7XjpWPH2jc8c1xoxO63GZiLumk8mO9VzleGW6O03fQ9z6pOE1ueSg +WnqHQYLbb5KizbiLen4xpa13cjZ2KFKJBkBEn2yOXXSOGP/yuWf1nQ1QumHCFFxf +SRrJaaVqR8Ow6yPIjeCFT0IyeoGP5ihlxTvgSo+HeQx1wuYcBIG6clx4BGEgUa2N +kaUF6v6EBl/mfX6YkhzvDygaS3men1XRgAkNFPXN9L7XVQdAh2hJSenq73seCJcc +lD6Pr4U3VdWaTNYNZqpySspfJ6vp4XGNJFWZiaHPC5CALjgMzljdq9Xohedl2v0i +zFZ4T3Zd+RT1941yD5rqlTnaqscpPnZpEUkULjH63v42/vLRSVkZOb6uSdOTL/c3 +bxDr4ZbN6cPY5As+XADPgOALuiQql+bRYOZOQL6i5lwtepfvmT6YGZZMk0WKhDcD +C/cWX7z7834T2yYez2OmFdTr1UCmGd9IqTTQ01JTgr02y5lCN5J4KlG0SQBnQeQB +Pj+gi1WElCIsBIX67WNCss5bpzn+T9cvMD5w2uG94ceT7jbIQ8LQ5x90kn+4HKr0 +PnD937DKLY+HPbm5l9CIhmsX+mWUOcqqWSvxBWeJSk4Qk60K3G/oQeY= -----END CERTIFICATE----- diff --git a/glanceclient/tests/unit/var/certificate.crt b/glanceclient/tests/unit/var/certificate.crt index 06c02ab..64b2291 100644 --- a/glanceclient/tests/unit/var/certificate.crt +++ b/glanceclient/tests/unit/var/certificate.crt @@ -1,66 +1,34 @@ -# Certificate: -# Data: -# Version: 3 (0x2) -# Serial Number: 1 (0x1) -# Signature Algorithm: sha1WithRSAEncryption -# Issuer: O=Openstack CA Org, OU=Openstack Test CA/emailAddress=admin@ca.example.com, -# L=State CA, ST=CA, C=AU, CN=Openstack Test Certificate Authority -# Validity -# Not Before: Nov 16 12:50:19 2012 GMT -# Not After : Apr 3 12:50:19 2040 GMT -# Subject: O=Openstack Test Org, OU=Openstack Test Unit/emailAddress=admin@example.com, -# L=State1, ST=CA, C=US, CN=0.0.0.0 -# Subject Public Key Info: -# Public Key Algorithm: rsaEncryption -# RSA Public Key: (4096 bit) -# Modulus (4096 bit): -# 00:d4:bb:3a:c4:a0:06:54:31:23:5d:b0:78:5a:be: -# 45:44:ae:a1:89:86:11:d8:ca:a8:33:b0:4f:f3:e1: -# . -# . -# . -# Exponent: 65537 (0x10001) -# X509v3 extensions: -# X509v3 Subject Alternative Name: -# DNS:alt1.example.com, DNS:alt2.example.com -# Signature Algorithm: sha1WithRSAEncryption -# 2c:fc:5c:87:24:bd:4a:fa:40:d2:2e:35:a4:2a:f3:1c:b3:67: -# b0:e4:8a:cd:67:6b:55:50:d4:cb:dd:2d:26:a5:15:62:90:a3: -# . -# . -# . -----BEGIN CERTIFICATE----- -MIIGADCCA+igAwIBAgIBATANBgkqhkiG9w0BAQUFADCBuDEZMBcGA1UEChMQT3Bl -bnN0YWNrIENBIE9yZzEaMBgGA1UECxMRT3BlbnN0YWNrIFRlc3QgQ0ExIzAhBgkq -hkiG9w0BCQEWFGFkbWluQGNhLmV4YW1wbGUuY29tMREwDwYDVQQHEwhTdGF0ZSBD -QTELMAkGA1UECBMCQ0ExCzAJBgNVBAYTAkFVMS0wKwYDVQQDEyRPcGVuc3RhY2sg -VGVzdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTIxMTE2MTI1MDE5WhcNNDAw -NDAzMTI1MDE5WjCBmjEbMBkGA1UEChMST3BlbnN0YWNrIFRlc3QgT3JnMRwwGgYD -VQQLExNPcGVuc3RhY2sgVGVzdCBVbml0MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBl -eGFtcGxlLmNvbTEPMA0GA1UEBxMGU3RhdGUxMQswCQYDVQQIEwJDQTELMAkGA1UE -BhMCVVMxEDAOBgNVBAMTBzAuMC4wLjAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDUuzrEoAZUMSNdsHhavkVErqGJhhHYyqgzsE/z4UYehaMqnKTgwhQ0 -T5Hf3GmlIBt4I96/3cxj0qSLrdR81fM+5Km8lIlVHwVn1y6LKcMlaUC4K+sgDLcj -hZfbf9+fMkcur3WlNzKpAEaIosWwsu6YvYc+W/nPBpKxMbOZ4fZiPMEo8Pxmw7sl -/6hnlBOJj7dpZOZpHhVPZgzYNVoyfKCZiwgdxH4JEYa+EQos87+2Nwhs7bCgrTLL -ppCUvpobwZV5w4O0D6INpUfBmsr4IAuXeFWZa61vZYqhaVbAbTTlUzOLGh7Z2uz9 -gt75iSR2J0e2xntVaUIYLIAUNOO2edk8NMAuIOGr2EIyC7i2O/BTti2YjGNO7SsE -ClxiIFKjYahylHmNrS1Q/oMAcJppmhz+oOCmKOMmAZXYAH1A3gs/sWphJpgv/MWt -6Ji24VpFaJ+o4bHILlqIpuvL4GLIOkmxVP639khaumgKtgNIUTKJ/V6t/J31WARf -xKxlBQTTzV/Be+84YJiiddx8eunU8AorPyAJFzsDPTJpFUB4Q5BwAeDGCySgxJpU -qM2MTETBycdiVToM4SWkRsOZgZxQ+AVfkkqDct2Bat2lg9epcIez8PrsohQjQbmi -qUUL2c3de4kLYzIWF8EN3P2Me/7b06jbn4c7Fly/AN6tJOG23BzhHQIDAQABozEw -LzAtBgNVHREEJjAkghBhbHQxLmV4YW1wbGUuY29tghBhbHQyLmV4YW1wbGUuY29t -MA0GCSqGSIb3DQEBBQUAA4ICAQAs/FyHJL1K+kDSLjWkKvMcs2ew5IrNZ2tVUNTL -3S0mpRVikKOQbNLh5B6Q7eQIvilCdkuit7o2HrpxQHsRor5b4+LyjSLoltyE7dgr -ioP5nkKH+ujw6PtMxJCiKvvI+6cVHh6EV2ZkddvbJLVBVVZmB4H64xocS3rrQj19 -SXFYVrEjqdLzdGPNIBR+XVnTCeofXg1rkMaU7JuY8nRztee8PRVcKYX6scPfZJb8 -+Ea2dsTmtQP4H9mk+JiKGYhEeMLVmjiv3q7KIFownTKZ88K6QbpW2Nj66ItvphoT -QqI3rs6E8N0BhftiCcxXtXg+o4utfcnp8jTXX5tVnv44FqtWx7Gzg8XTLPri+ZEB -5IbgU4Q3qFicenBfjwZhH3+GNe52/wLVZLYjal5RPVSRdu9UEDeDAwTCMZSLF4lC -rc9giQCMnJ4ISi6C7xH+lDZGFqcJd4oXg/ue9aOJJAFTwhd83fdCHhUu431iPrts -NubfrHLMeUjluFgIWmhEZg+XTjB1SQeQzNaZiMODaAv4/40ZVKxvNpDFwIIsPUDf -+uC+fv1Q8+alqVMl2ouVyr8ut43HWNV6CJHXODvFp5irjxzVSgLtYDVUInkDFJEs -tFpTY21/zVAHIvsj2n4F1231nILR6vBp/WbwBY7r7j0oRtbaO3B1Q6tsbCZQRkKU -tdc5rw== +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 +9l4gwJ1ojNB2abF4LOEf5bU= -----END CERTIFICATE----- diff --git a/glanceclient/tests/unit/var/privatekey.key b/glanceclient/tests/unit/var/privatekey.key index 5b47d44..6cd8725 100644 --- a/glanceclient/tests/unit/var/privatekey.key +++ b/glanceclient/tests/unit/var/privatekey.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/glanceclient/tests/utils.py b/glanceclient/tests/utils.py index 3deddb1..730b928 100644 --- a/glanceclient/tests/utils.py +++ b/glanceclient/tests/utils.py @@ -14,10 +14,10 @@ # under the License. import copy +import io import json -import six -import six.moves.urllib.parse as urlparse import testtools +from urllib import parse from glanceclient.v2 import schemas @@ -38,11 +38,11 @@ class FakeAPI(object): fixture = self.fixtures[sort_url_by_query_keys(url)][method] data = fixture[1] - if isinstance(fixture[1], six.string_types): + if isinstance(fixture[1], str): try: data = json.loads(fixture[1]) except ValueError: - data = six.StringIO(fixture[1]) + data = io.StringIO(fixture[1]) return FakeResponse(fixture[0], fixture[1]), data @@ -141,7 +141,7 @@ class FakeResponse(object): @property def text(self): - if isinstance(self.content, six.binary_type): + if isinstance(self.content, bytes): return self.content.decode('utf-8') return self.content @@ -166,7 +166,7 @@ class TestCase(testtools.TestCase): 'verify': True} -class FakeTTYStdout(six.StringIO): +class FakeTTYStdout(io.StringIO): """A Fake stdout that try to emulate a TTY device as much as possible.""" def isatty(self): @@ -177,7 +177,7 @@ class FakeTTYStdout(six.StringIO): if data.startswith('\r'): self.seek(0) data = data[1:] - return six.StringIO.write(self, data) + return io.StringIO.write(self, data) class FakeNoTTYStdout(FakeTTYStdout): @@ -197,24 +197,24 @@ def sort_url_by_query_keys(url): :param url: url which will be ordered by query keys :returns url: url with ordered query keys """ - parsed = urlparse.urlparse(url) - queries = urlparse.parse_qsl(parsed.query, True) + parsed = parse.urlparse(url) + queries = parse.parse_qsl(parsed.query, True) sorted_query = sorted(queries, key=lambda x: x[0]) - encoded_sorted_query = urlparse.urlencode(sorted_query, True) + encoded_sorted_query = parse.urlencode(sorted_query, True) url_parts = (parsed.scheme, parsed.netloc, parsed.path, parsed.params, encoded_sorted_query, parsed.fragment) - return urlparse.urlunparse(url_parts) + return parse.urlunparse(url_parts) def build_call_record(method, url, headers, data): """Key the request body be ordered if it's a dict type.""" if isinstance(data, dict): data = sorted(data.items()) - if isinstance(data, six.string_types): + if isinstance(data, str): # NOTE(flwang): For image update, the data will be a 'list' which # contains operation dict, such as: [{"op": "remove", "path": "/a"}] try: diff --git a/glanceclient/v1/apiclient/base.py b/glanceclient/v1/apiclient/base.py index a12a8cc..165e6de 100644 --- a/glanceclient/v1/apiclient/base.py +++ b/glanceclient/v1/apiclient/base.py @@ -41,8 +41,7 @@ import abc import copy from oslo_utils import strutils -import six -from six.moves.urllib import parse +import urllib.parse from glanceclient._i18n import _ from glanceclient.v1.apiclient import exceptions @@ -224,8 +223,7 @@ class BaseManager(HookableMixin): return self.client.delete(url) -@six.add_metaclass(abc.ABCMeta) -class ManagerWithFind(BaseManager): +class ManagerWithFind(BaseManager, metaclass=abc.ABCMeta): """Manager with additional `find()`/`findall()` methods.""" @abc.abstractmethod @@ -350,10 +348,11 @@ class CrudManager(BaseManager): """ kwargs = self._filter_kwargs(kwargs) + query = urllib.parse.urlencode(kwargs) if kwargs else '', return self._list( '%(base_url)s%(query)s' % { 'base_url': self.build_url(base_url=base_url, **kwargs), - 'query': '?%s' % parse.urlencode(kwargs) if kwargs else '', + 'query': '?%s' % query, }, self.collection_key) @@ -389,10 +388,11 @@ class CrudManager(BaseManager): """ kwargs = self._filter_kwargs(kwargs) + query = urllib.parse.urlencode(kwargs) if kwargs else '', rl = self._list( '%(base_url)s%(query)s' % { 'base_url': self.build_url(base_url=base_url, **kwargs), - 'query': '?%s' % parse.urlencode(kwargs) if kwargs else '', + 'query': '?%s' % query, }, self.collection_key) num = len(rl) diff --git a/glanceclient/v1/apiclient/exceptions.py b/glanceclient/v1/apiclient/exceptions.py index f3d778c..27b3eba 100644 --- a/glanceclient/v1/apiclient/exceptions.py +++ b/glanceclient/v1/apiclient/exceptions.py @@ -36,8 +36,6 @@ Exception definitions. import inspect import sys -import six - from glanceclient._i18n import _ @@ -461,7 +459,7 @@ def from_response(response, method, url): kwargs["message"] = (error.get("message") or error.get("faultstring")) kwargs["details"] = (error.get("details") or - six.text_type(body)) + str(body)) elif content_type.startswith("text/"): kwargs["details"] = getattr(response, 'text', '') diff --git a/glanceclient/v1/apiclient/utils.py b/glanceclient/v1/apiclient/utils.py index 814a37b..7d3e4e0 100644 --- a/glanceclient/v1/apiclient/utils.py +++ b/glanceclient/v1/apiclient/utils.py @@ -26,7 +26,6 @@ from oslo_utils import encodeutils from oslo_utils import uuidutils -import six from glanceclient._i18n import _ from glanceclient.v1.apiclient import exceptions @@ -52,10 +51,7 @@ def find_resource(manager, name_or_id, **find_args): # now try to get entity as uuid try: - if six.PY2: - tmp_id = encodeutils.safe_encode(name_or_id) - else: - tmp_id = encodeutils.safe_decode(name_or_id) + tmp_id = encodeutils.safe_decode(name_or_id) if uuidutils.is_uuid_like(tmp_id): return manager.get(tmp_id) diff --git a/glanceclient/v1/images.py b/glanceclient/v1/images.py index 966d45a..b8e2ee2 100644 --- a/glanceclient/v1/images.py +++ b/glanceclient/v1/images.py @@ -17,8 +17,7 @@ import copy from oslo_utils import encodeutils from oslo_utils import strutils -import six -import six.moves.urllib.parse as urlparse +import urllib.parse from glanceclient.common import utils from glanceclient.v1.apiclient import base @@ -101,7 +100,7 @@ class ImageManager(base.ManagerWithFind): # headers will be encoded later, before the # request is sent. def to_str(value): - if not isinstance(value, six.string_types): + if not isinstance(value, str): return str(value) return value @@ -129,7 +128,7 @@ class ImageManager(base.ManagerWithFind): """ image_id = base.getid(image) resp, body = self.client.head('/v1/images/%s' - % urlparse.quote(str(image_id))) + % urllib.parse.quote(str(image_id))) meta = self._image_meta_from_headers(resp.headers) return_request_id = kwargs.get('return_req_id', None) if return_request_id is not None: @@ -145,7 +144,7 @@ class ImageManager(base.ManagerWithFind): """ image_id = base.getid(image) resp, body = self.client.get('/v1/images/%s' - % urlparse.quote(str(image_id))) + % urllib.parse.quote(str(image_id))) content_length = int(resp.headers.get('content-length', 0)) checksum = resp.headers.get('x-image-meta-checksum', None) if do_checksum and checksum is not None: @@ -225,7 +224,7 @@ class ImageManager(base.ManagerWithFind): def paginate(qp, return_request_id=None): for param, value in qp.items(): - if isinstance(value, six.string_types): + if isinstance(value, str): # Note(flaper87) Url encoding should # be moved inside http utils, at least # shouldn't be here. @@ -234,7 +233,7 @@ class ImageManager(base.ManagerWithFind): # trying to encode them qp[param] = encodeutils.safe_decode(value) - url = '/v1/images/detail?%s' % urlparse.urlencode(qp) + url = '/v1/images/detail?%s' % urllib.parse.urlencode(qp) images, resp = self._list(url, "images") if return_request_id is not None: diff --git a/glanceclient/v1/shell.py b/glanceclient/v1/shell.py index 8a4d29d..682ca98 100644 --- a/glanceclient/v1/shell.py +++ b/glanceclient/v1/shell.py @@ -13,8 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -from __future__ import print_function - import copy import functools import os diff --git a/glanceclient/v2/images.py b/glanceclient/v2/images.py index b07eecc..341485d 100644 --- a/glanceclient/v2/images.py +++ b/glanceclient/v2/images.py @@ -17,8 +17,7 @@ import hashlib import json from oslo_utils import encodeutils from requests import codes -import six -from six.moves.urllib import parse +import urllib.parse import warlock from glanceclient.common import utils @@ -55,7 +54,7 @@ class Controller(object): @staticmethod def _wrap(value): - if isinstance(value, six.string_types): + if isinstance(value, str): return [value] return value @@ -142,19 +141,19 @@ class Controller(object): tags_url_params = [] for tag in tags: - if not isinstance(tag, six.string_types): + if not isinstance(tag, str): raise exc.HTTPBadRequest("Invalid tag value %s" % tag) tags_url_params.append({'tag': encodeutils.safe_encode(tag)}) for param, value in filters.items(): - if isinstance(value, six.string_types): + if isinstance(value, str): filters[param] = encodeutils.safe_encode(value) - url = '/v2/images?%s' % parse.urlencode(filters) + url = '/v2/images?%s' % urllib.parse.urlencode(filters) for param in tags_url_params: - url = '%s&%s' % (url, parse.urlencode(param)) + url = '%s&%s' % (url, urllib.parse.urlencode(param)) if 'sort' in kwargs: if 'sort_key' in kwargs or 'sort_dir' in kwargs: @@ -178,7 +177,7 @@ class Controller(object): for dir in sort_dir: url = '%s&sort_dir=%s' % (url, dir) - if isinstance(kwargs.get('marker'), six.string_types): + if isinstance(kwargs.get('marker'), str): url = '%s&marker=%s' % (url, kwargs['marker']) for image, resp in paginate(url, page_size, limit): diff --git a/glanceclient/v2/metadefs.py b/glanceclient/v2/metadefs.py index a6df87a..1b641ac 100644 --- a/glanceclient/v2/metadefs.py +++ b/glanceclient/v2/metadefs.py @@ -14,8 +14,7 @@ # under the License. from oslo_utils import encodeutils -import six -from six.moves.urllib import parse +import urllib.parse import warlock from glanceclient.common import utils @@ -89,7 +88,7 @@ class NamespaceController(object): @utils.add_req_id_to_object() def _get(self, namespace, header=None, **kwargs): """Get one namespace.""" - query_params = parse.urlencode(kwargs) + query_params = urllib.parse.urlencode(kwargs) if kwargs: query_params = '?%s' % query_params @@ -179,10 +178,10 @@ class NamespaceController(object): for param, value in filters.items(): if isinstance(value, list): filters[param] = encodeutils.safe_encode(','.join(value)) - elif isinstance(value, six.string_types): + elif isinstance(value, str): filters[param] = encodeutils.safe_encode(value) - url = '/v2/metadefs/namespaces?%s' % parse.urlencode(filters) + url = '/v2/metadefs/namespaces?%s' % urllib.parse.urlencode(filters) for namespace, resp in paginate(url): yield namespace, resp diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py index 8414308..592b2da 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -235,6 +235,9 @@ def do_image_create_via_import(gc, args): # determine if backend is valid _validate_backend(backend, gc) elif stores: + # NOTE(jokke): Making sure here that we do not include the stores in + # the create call + fields.pop("stores") stores = str(stores).split(',') for store in stores: # determine if backend is valid diff --git a/glanceclient/v2/tasks.py b/glanceclient/v2/tasks.py index 177c8bf..6649f4b 100644 --- a/glanceclient/v2/tasks.py +++ b/glanceclient/v2/tasks.py @@ -14,8 +14,9 @@ # License for the specific language governing permissions and limitations # under the License. +import urllib.parse + from oslo_utils import encodeutils -import six import warlock from glanceclient.common import utils @@ -85,10 +86,10 @@ class Controller(object): % ', '.join(SORT_DIR_VALUES)) for param, value in filters.items(): - if isinstance(value, six.string_types): + if isinstance(value, str): filters[param] = encodeutils.safe_encode(value) - url = '/v2/tasks?%s' % six.moves.urllib.parse.urlencode(filters) + url = '/v2/tasks?%s' % urllib.parse.urlencode(filters) for task, resp in paginate(url): # NOTE(flwang): remove 'self' for now until we have an elegant # way to pass it into the model constructor without conflict diff --git a/lower-constraints.txt b/lower-constraints.txt index ecb84ad..8e63056 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -2,11 +2,11 @@ alabaster==0.7.10 appdirs==1.3.0 asn1crypto==0.23.0 Babel==2.3.4 -cffi==1.7.0 +cffi==1.14.0 cliff==2.8.0 cmd2==0.8.0 coverage==4.0 -cryptography==2.1 +cryptography==2.7 ddt==1.2.1 debtcollector==1.2.0 docutils==0.11 @@ -31,7 +31,6 @@ monotonic==0.6 msgpack-python==0.4.0 netaddr==0.7.18 netifaces==0.10.4 -openstackdocstheme==1.20.0 ordereddict==1.1 os-client-config==1.28.0 os-testr==1.0.0 @@ -56,16 +55,12 @@ python-dateutil==2.5.3 python-mimeparse==1.6.0 python-subunit==1.0.0 pytz==2013.6 -PyYAML==3.12 -reno==2.5.0 +PyYAML==3.13 requests-mock==1.2.0 requests==2.14.2 requestsexceptions==1.2.0 rfc3986==0.3.1 -six==1.10.0 snowballstemmer==1.2.1 -Sphinx==1.6.2 -sphinxcontrib-websupport==1.0.1 stestr==2.0.0 stevedore==1.20.0 tempest==17.1.0 diff --git a/releasenotes/notes/fix_1889666-22dc97ce577eccc6.yaml b/releasenotes/notes/fix_1889666-22dc97ce577eccc6.yaml new file mode 100644 index 0000000..553c377 --- /dev/null +++ b/releasenotes/notes/fix_1889666-22dc97ce577eccc6.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Bug 1889666_: 'stores' property added when using image-create-via-import --stores <list> + + .. _1889666: https://bugs.launchpad.net/glance/+bug/1889666 diff --git a/releasenotes/notes/sess_client_grid-3c2101609110f413.yaml b/releasenotes/notes/sess_client_grid-3c2101609110f413.yaml new file mode 100644 index 0000000..4552c43 --- /dev/null +++ b/releasenotes/notes/sess_client_grid-3c2101609110f413.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + * Bug 1886650_: Glance client does not correctly forward global request IDs + + .. _1886650: https://code.launchpad.net/bugs/1886650 diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py index 75aab4d..d20e2f4 100644 --- a/releasenotes/source/conf.py +++ b/releasenotes/source/conf.py @@ -29,8 +29,6 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) -import openstackdocstheme - # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. @@ -41,6 +39,7 @@ import openstackdocstheme # ones. extensions = [ 'reno.sphinxext', + 'openstackdocstheme' ] # Add any paths that contain templates here, relative to this directory. @@ -59,6 +58,11 @@ master_doc = 'index' project = u'glanceclient Release Notes' copyright = u'2016, Glance Developers' +openstackdocs_repo_name = 'openstack/python-glanceclient' +openstackdocs_bug_project = 'python-glanceclient' +openstackdocs_bug_tag = '' +openstackdocs_auto_name = False + # Release notes are not versioned, so we don't need to set version or release version = '' release = '' @@ -93,7 +97,7 @@ exclude_patterns = [] # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = 'native' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -113,10 +117,6 @@ html_theme = 'openstackdocs' # documentation. # html_theme_options = {} -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] -html_theme_path = [openstackdocstheme.get_html_theme_path()] - # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". # html_title = None diff --git a/requirements.txt b/requirements.txt index 25b670a..ca8abaf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,6 @@ PrettyTable<0.8,>=0.7.1 # BSD keystoneauth1>=3.6.2 # Apache-2.0 requests>=2.14.2 # Apache-2.0 warlock<2,>=1.2.0 # Apache-2.0 -six>=1.10.0 # MIT oslo.utils>=3.33.0 # Apache-2.0 oslo.i18n>=3.15.3 # Apache-2.0 wrapt>=1.7.0 # BSD License @@ -69,7 +69,7 @@ show-source = True exclude = .venv*,.tox,dist,*egg,build,.git,doc,*lib/python*,.update-venv [hacking] -import_exceptions = six.moves,glanceclient._i18n +import_exceptions = glanceclient._i18n [testenv:lower-constraints] basepython = python3 |