From b513c8db4bf6a5b2eb0366117ca22e042dd3529e Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Mon, 15 Jun 2020 21:28:17 +0200 Subject: [PATCH] Do not use the six library. Change-Id: I3dbfcfa0f5f590a41ed549afd44537d8ed41433a --- glanceclient/common/http.py | 24 ++++++---------- glanceclient/common/https.py | 21 ++++---------- glanceclient/common/progressbar.py | 4 +-- glanceclient/common/utils.py | 21 ++++++-------- glanceclient/exc.py | 5 +--- glanceclient/shell.py | 38 ++----------------------- glanceclient/tests/unit/test_shell.py | 21 -------------- glanceclient/v1/apiclient/base.py | 12 ++++---- glanceclient/v1/apiclient/exceptions.py | 4 +-- glanceclient/v1/apiclient/utils.py | 6 +--- glanceclient/v1/images.py | 13 ++++----- glanceclient/v2/images.py | 15 +++++----- glanceclient/v2/metadefs.py | 9 +++--- glanceclient/v2/tasks.py | 7 +++-- lower-constraints.txt | 1 - requirements.txt | 1 - tox.ini | 2 +- 17 files changed, 57 insertions(+), 147 deletions(-) diff --git a/glanceclient/common/http.py b/glanceclient/common/http.py index 6973f60e..76ad0c39 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) diff --git a/glanceclient/common/https.py b/glanceclient/common/https.py index deb7eb03..94aeeb32 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 6cf0df39..bb8b21b4 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 0fde763f..20256b8a 100644 --- a/glanceclient/common/utils.py +++ b/glanceclient/common/utils.py @@ -21,12 +21,11 @@ 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 +160,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 +215,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 +342,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 +398,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 +443,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 +463,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 eee47cac..5efe8056 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 3dfa14a6..d0028fe2 100644 --- a/glanceclient/shell.py +++ b/glanceclient/shell.py @@ -31,8 +31,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 +258,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 +521,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 +591,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='', nargs='?', help='Display help for .') def do_help(self, args, parser): diff --git a/glanceclient/tests/unit/test_shell.py b/glanceclient/tests/unit/test_shell.py index 48232249..74d1c333 100644 --- a/glanceclient/tests/unit/test_shell.py +++ b/glanceclient/tests/unit/test_shell.py @@ -160,27 +160,6 @@ class ShellTest(testutils.TestCase): sys.stderr = orig_stderr return (stdout, stderr) - def test_fixup_subcommand(self): - arglist = [u'image-list', u'--help'] - 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:] - 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' diff --git a/glanceclient/v1/apiclient/base.py b/glanceclient/v1/apiclient/base.py index a12a8cc0..165e6de1 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 f3d778cd..27b3ebab 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 814a37bf..7d3e4e05 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 966d45a4..b8e2ee2c 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/v2/images.py b/glanceclient/v2/images.py index b07eecc2..341485db 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 a6df87a1..1b641ac7 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/tasks.py b/glanceclient/v2/tasks.py index 177c8bf7..6649f4b4 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 d98e40b7..6b4229ea 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -60,7 +60,6 @@ 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 stestr==2.0.0 stevedore==1.20.0 diff --git a/requirements.txt b/requirements.txt index 25b670a0..ca8abafa 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 diff --git a/tox.ini b/tox.ini index f001df98..13238b1e 100644 --- a/tox.ini +++ b/tox.ini @@ -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