Remove final six usage

We also update docs since guidance has necessarily changed here.

Change-Id: I7c24a1aa3545f3499a7a2ce30b73e2656666c764
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
Stephen Finucane 2021-12-21 12:36:37 +00:00
parent f68e04f268
commit 33741138d9
12 changed files with 17 additions and 112 deletions

View File

@ -26,38 +26,9 @@ The Great Change
With the demise of Python 2.7 in January 2020, beginning with the Ussuri
development cycle, Glance only needs to support Python 3 runtimes (in
particular, 3.6 and 3.7). Thus we can begin to incorporate Python 3
language features and remove Python 2 compatibility code. At the same
time, however, we are still supporting stable branches that must support
Python 2. Our biggest interaction with the stable branches is backporting
bugfixes, where in the ideal case, we're just doing a simple cherry-pick of
a commit from master to the stable branches. You can see that there's some
tension here.
With that in mind, here are some guidelines for reviewers and developers
that the Glance community has agreed on during this phase where we want to
write pure Python 3 but still must support Python 2 code.
.. _transition-guidelines:
Python 2 to Python 3 transition guidelines
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* We need to be checking the code coverage of test cases very carefully so
that new code has excellent coverage. The idea is that we want these
tests to fail when a backport is proposed to a stable branch and the
tests are run under Python 2 (if the code is using any Python-3-only
language features).
* New features can use Python-3-only language constructs, but bugfixes
likely to be backported should be more conservative and write for
Python 2 compatibility.
* The code for drivers may continue to use the six compatibility library at
their discretion.
* We will not remove six from mainline Cinder code that impacts the drivers
(for example, classes they inherit from).
* We can remove six from code that doesn't impact drivers, keeping in mind
that backports may be more problematic, and hence making sure that we have
really good test coverage.
particular, 3.6 and 3.7). There was a four cycle transition period, but
starting in the Yoga development cycle, all Python 2 compatibility code
has been removed and only Python 3 is supposed.
Unit Tests
----------

View File

@ -24,7 +24,6 @@ the local cached copy of the image file is returned.
import http.client as http
import re
import six
from oslo_log import log as logging
import webob
@ -220,8 +219,7 @@ class CacheFilter(wsgi.Middleware):
# https://github.com/Pylons/webob/issues/86
response.headers['Content-Type'] = 'application/octet-stream'
if image.checksum:
response.headers['Content-MD5'] = (image.checksum.encode('utf-8')
if six.PY2 else image.checksum)
response.headers['Content-MD5'] = image.checksum
response.headers['Content-Length'] = str(image.size)
return response

View File

@ -25,7 +25,6 @@ from oslo_log import log as logging
import oslo_serialization.jsonutils as json
from oslo_utils import encodeutils
from oslo_utils import uuidutils
import six
import webob.exc
from glance.api import common
@ -270,8 +269,6 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
def _inject_location_header(self, response, task):
location = self._get_task_location(task)
if six.PY2:
location = location.encode('utf-8')
response.headers['Location'] = location
def _get_task_location(self, task):

View File

@ -26,7 +26,6 @@ from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import encodeutils
from oslo_utils import uuidutils
import six
from webob import exc
from glance.common import config
@ -395,11 +394,7 @@ def replication_dump(options, args):
'data_filename': data_filename})
# Dump glance information
if six.PY3:
f = open(data_path, 'w', encoding='utf-8')
else:
f = open(data_path, 'w')
with f:
with open(data_path, 'w', encoding='utf-8') as f:
f.write(jsonutils.dumps(image))
if image['status'] == 'active' and not options.metaonly:

View File

@ -44,7 +44,6 @@ except ImportError:
from oslo_log import log as logging
from oslo_utils import encodeutils
from oslo_utils import netutils
import six
from glance.common import auth
from glance.common import exception
@ -411,11 +410,7 @@ class BaseClient(object):
:returns: Dictionary with encoded headers'
names and values
"""
if six.PY3:
to_str = str
else:
to_str = encodeutils.safe_encode
return {to_str(h): to_str(v) for h, v in headers.items()}
return {str(h): str(v) for h, v in headers.items()}
@handle_redirects
def _do_request(self, method, url, body, headers):
@ -512,9 +507,7 @@ class BaseClient(object):
return res.getheader('Retry-After')
def read_body(res):
body = res.read()
if six.PY3:
body = body.decode('utf-8')
body = res.read().decode('utf-8')
return body
status_code = self.get_status_code(res)

View File

@ -26,7 +26,6 @@ from cryptography.hazmat.primitives.ciphers import algorithms
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers import modes
from oslo_utils import encodeutils
import six
def urlsafe_encrypt(key, plaintext, blocksize=16):
@ -48,7 +47,7 @@ def urlsafe_encrypt(key, plaintext, blocksize=16):
# NOTE(rosmaita): I know this looks stupid, but we can't just
# use os.urandom() to get the bytes because we use char(0) as
# a delimiter
pad = b''.join(six.int2byte(random.SystemRandom().randint(1, 0xFF))
pad = b''.join(bytes((random.SystemRandom().randint(1, 0xFF),))
for i in range(pad_length - 1))
# We use chr(0) as a delimiter between text and padding
return text + b'\0' + pad
@ -63,8 +62,7 @@ def urlsafe_encrypt(key, plaintext, blocksize=16):
encryptor = cypher.encryptor()
padded = encryptor.update(pad(plaintext)) + encryptor.finalize()
encoded = base64.urlsafe_b64encode(init_vector + padded)
if six.PY3:
encoded = encoded.decode('ascii')
encoded = encoded.decode('ascii')
return encoded
@ -88,6 +86,5 @@ def urlsafe_decrypt(key, ciphertext):
decryptor = cypher.decryptor()
padded = decryptor.update(ciphertext[16:]) + decryptor.finalize()
text = padded[:padded.rfind(b'\0')]
if six.PY3:
text = text.decode('utf-8')
text = text.decode('utf-8')
return text

View File

@ -39,7 +39,6 @@ from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import netutils
from oslo_utils import strutils
import six
from webob import exc
from glance.common import exception
@ -443,8 +442,6 @@ def get_test_suite_socket():
if GLANCE_TEST_SOCKET_FD_STR in os.environ:
fd = int(os.environ[GLANCE_TEST_SOCKET_FD_STR])
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
if six.PY2:
sock = socket.SocketType(_sock=sock)
sock.listen(CONF.backlog)
del os.environ[GLANCE_TEST_SOCKET_FD_STR]
os.close(fd)

View File

@ -45,7 +45,6 @@ from oslo_utils import encodeutils
from oslo_utils import strutils
from osprofiler import opts as profiler_opts
import routes.middleware
import six
import webob.dec
import webob.exc
from webob import multidict
@ -1104,26 +1103,6 @@ class Request(webob.Request):
# not be inherited.
webob.Request.body_file.fset(self, value)
@property
def params(self):
"""Override params property of webob.request.BaseRequest.
Added an 'encoded_params' attribute in case of PY2 to avoid
encoding values in next subsequent calls to the params property.
"""
if six.PY2:
encoded_params = getattr(self, 'encoded_params', None)
if encoded_params is None:
params = super(Request, self).params
params_dict = multidict.MultiDict()
for key, value in params.items():
params_dict.add(key, encodeutils.safe_encode(value))
setattr(self, 'encoded_params',
multidict.NestedMultiDict(params_dict))
return self.encoded_params
return super(Request, self).params
def best_match_content_type(self):
"""Determine the requested response content-type."""
supported = ('application/json',)
@ -1352,9 +1331,8 @@ class Resource(object):
action_result = self.dispatch(self.controller, action,
request, **action_args)
except webob.exc.WSGIHTTPException as e:
exc_info = sys.exc_info()
e = translate_exception(request, e)
six.reraise(type(e), e, exc_info[2])
raise e.with_traceback(sys.exc_info()[2])
except UnicodeDecodeError:
msg = _("Error decoding your request. Either the URL or the "
"request body contained characters that could not be "
@ -1373,10 +1351,6 @@ class Resource(object):
try:
response = webob.Response(request=request)
self.dispatch(self.serializer, action, response, action_result)
# encode all headers in response to utf-8 to prevent unicode errors
for name, value in list(response.headers.items()):
if six.PY2 and isinstance(value, str):
response.headers[name] = encodeutils.safe_encode(value)
return response
except webob.exc.WSGIHTTPException as e:
return translate_exception(request, e)

View File

@ -61,7 +61,6 @@ from oslo_log import log as logging
from oslo_utils import encodeutils
from oslo_utils import excutils
from oslo_utils import fileutils
import six
import xattr
from glance.common import exception
@ -477,9 +476,7 @@ def set_xattr(path, key, value):
"""
namespaced_key = _make_namespaced_xattr_key(key)
if not isinstance(value, bytes):
value = str(value)
if six.PY3:
value = value.encode('utf-8')
value = str(value).encode('utf-8')
xattr.setxattr(path, namespaced_key, value)

View File

@ -28,7 +28,6 @@ import fixtures
from oslo_concurrency import processutils
from oslo_serialization import jsonutils
import routes
import six
import webob
from glance.api.v2 import router as router_v2
@ -111,15 +110,9 @@ class RequestTest(test_utils.BaseTestCase):
self.assertEqual("application/json", result)
def test_params(self):
if six.PY2:
expected = webob.multidict.NestedMultiDict({
'limit': '20', 'name':
'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82',
'sort_key': 'name', 'sort_dir': 'asc'})
else:
expected = webob.multidict.NestedMultiDict({
'limit': '20', 'name': 'Привет', 'sort_key': 'name',
'sort_dir': 'asc'})
expected = webob.multidict.NestedMultiDict({
'limit': '20', 'name': 'Привет', 'sort_key': 'name',
'sort_dir': 'asc'})
request = wsgi.Request.blank("/?limit=20&name=%D0%9F%D1%80%D0%B8"
"%D0%B2%D0%B5%D1%82&sort_key=name"
@ -414,8 +407,7 @@ class ResourceTest(test_utils.BaseTestCase):
response = resource.__call__(request)
# ensure it has been encoded correctly
value = (response.headers['unicode_test'].decode('utf-8')
if six.PY2 else response.headers['unicode_test'])
value = response.headers['unicode_test']
self.assertEqual(for_openstack_comrades, value)

View File

@ -15,8 +15,6 @@
import os
import six
from glance.common import crypt
from glance.common import utils
from glance.tests import utils as test_utils
@ -33,9 +31,7 @@ class UtilsTestCase(test_utils.BaseTestCase):
plaintext_list = ['']
blocksize = 64
for i in range(3 * blocksize):
text = os.urandom(i)
if six.PY3:
text = text.decode('latin1')
text = os.urandom(i).decode('latin1')
plaintext_list.append(text)
for key in key_list:

View File

@ -33,8 +33,6 @@ Paste>=2.0.2 # MIT
jsonschema>=3.2.0 # MIT
python-keystoneclient>=3.8.0 # Apache-2.0
pyOpenSSL>=17.1.0 # Apache-2.0
# Required by openstack.common libraries
six>=1.11.0 # MIT
oslo.db>=5.0.0 # Apache-2.0
oslo.i18n>=5.0.0 # Apache-2.0