Fix Python 3 issues

* Replace unicode with six.text_type
* Replace "raise a, b, c" with six.reraise(a, b, c)
* Replace dict.iteritems() with six.iteritems(dict)
* Replace StringIO.StringIO with six.BytesIO for image content
* Get AssertionError from builtins, don't use the exceptions module
  which was removed in Python 3
* Open configuration file in text mode (not in binary mode) in
  functional tests
* Use absolute imports in artifacts_sample and image_artifact plugins
  instead of relative imports.
* Fix usage of __import__() function: the level parameter expects a
  positive integer, use level=0, not level=-1
* Get the input function from six.moves: use raw_input() on Python 2 and
  input() on Python 3. raw_input() was renamed to input() in Python 3.
* Unpacking parameters in function definition is no more possible:
  unpack the tuple manually in test_glance_replicator.py
* On Python 3, socket.fromfd() now returns directly the right socket
  type. It's not more needed to cast manually the result of
  socket.fromfd().

For more information on Python 3, see:
https://wiki.openstack.org/wiki/Python3

Change-Id: Iaa1a392590154058eab4645fb288d1534f66e528
This commit is contained in:
Victor Stinner 2015-05-21 08:51:39 -07:00 committed by Flavio Percoco
parent 609fda5643
commit 6652f4b029
13 changed files with 28 additions and 24 deletions

View File

@ -29,6 +29,7 @@ import time
from oslo_utils import timeutils from oslo_utils import timeutils
from glance.common import utils from glance.common import utils
from six.moves import input
# If ../glance/__init__.py exists, add ../ to Python search path, so that # If ../glance/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python... # it will override what happens to be installed in /usr/(local/)lib/python...
@ -467,7 +468,7 @@ def user_confirm(prompt, default=False):
else: else:
prompt_default = "[y/N]" prompt_default = "[y/N]"
answer = raw_input("%s %s " % (prompt, prompt_default)) answer = input("%s %s " % (prompt, prompt_default))
if answer == "": if answer == "":
return default return default

View File

@ -586,7 +586,8 @@ def get_test_suite_socket():
if GLANCE_TEST_SOCKET_FD_STR in os.environ: if GLANCE_TEST_SOCKET_FD_STR in os.environ:
fd = int(os.environ[GLANCE_TEST_SOCKET_FD_STR]) fd = int(os.environ[GLANCE_TEST_SOCKET_FD_STR])
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
sock = socket.SocketType(_sock=sock) if six.PY2:
sock = socket.SocketType(_sock=sock)
sock.listen(CONF.backlog) sock.listen(CONF.backlog)
del os.environ[GLANCE_TEST_SOCKET_FD_STR] del os.environ[GLANCE_TEST_SOCKET_FD_STR]
os.close(fd) os.close(fd)
@ -682,12 +683,12 @@ def no_4byte_params(f):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
def _is_match(some_str): def _is_match(some_str):
return (isinstance(some_str, unicode) and return (isinstance(some_str, six.text_type) and
REGEX_4BYTE_UNICODE.findall(some_str) != []) REGEX_4BYTE_UNICODE.findall(some_str) != [])
def _check_dict(data_dict): def _check_dict(data_dict):
# a dict of dicts has to be checked recursively # a dict of dicts has to be checked recursively
for key, value in data_dict.iteritems(): for key, value in six.iteritems(data_dict):
if isinstance(value, dict): if isinstance(value, dict):
_check_dict(value) _check_dict(value)
else: else:

View File

@ -873,7 +873,7 @@ class Resource(object):
request, **action_args) request, **action_args)
except webob.exc.WSGIHTTPException as e: except webob.exc.WSGIHTTPException as e:
exc_info = sys.exc_info() exc_info = sys.exc_info()
raise translate_exception(request, e), None, exc_info[2] six.reraise(translate_exception(request, e), None, exc_info[2])
try: try:
response = webob.Response(request=request) response = webob.Response(request=request)

View File

@ -1,5 +1,5 @@
from v1 import artifact as art1 from glance.contrib.plugins.artifacts_sample.v1 import artifact as art1
from v2 import artifact as art2 from glance.contrib.plugins.artifacts_sample.v2 import artifact as art2
MY_ARTIFACT = [art1.MyArtifact, art2.MyArtifact] MY_ARTIFACT = [art1.MyArtifact, art2.MyArtifact]

View File

@ -12,8 +12,8 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from v1 import image as v1 from glance.contrib.plugins.image_artifact.v1 import image as v1
from v1_1 import image as v1_1 from glance.contrib.plugins.image_artifact.v1_1 import image as v1_1
from v2 import image as v2 from glance.contrib.plugins.image_artifact.v2 import image as v2
versions = [v1.ImageAsAnArtifact, v1_1.ImageAsAnArtifact, v2.ImageAsAnArtifact] versions = [v1.ImageAsAnArtifact, v1_1.ImageAsAnArtifact, v2.ImageAsAnArtifact]

View File

@ -92,7 +92,7 @@ def from_migration_import(module_name, fromlist):
# Refer to images table # Refer to images table
""" """
module_path = 'glance.db.sqlalchemy.migrate_repo.versions.%s' % module_name module_path = 'glance.db.sqlalchemy.migrate_repo.versions.%s' % module_name
module = __import__(module_path, globals(), locals(), fromlist, -1) module = __import__(module_path, globals(), locals(), fromlist, 0)
return [getattr(module, item) for item in fromlist] return [getattr(module, item) for item in fromlist]

View File

@ -115,7 +115,7 @@ class Server(object):
utils.safe_mkdirs(conf_dir) utils.safe_mkdirs(conf_dir)
def override_conf(filepath, overridden): def override_conf(filepath, overridden):
with open(filepath, 'wb') as conf_file: with open(filepath, 'w') as conf_file:
conf_file.write(overridden) conf_file.write(overridden)
conf_file.flush() conf_file.flush()
return conf_file.name return conf_file.name
@ -207,7 +207,7 @@ class Server(object):
utils.safe_mkdirs(conf_dir) utils.safe_mkdirs(conf_dir)
conf_filepath = os.path.join(conf_dir, 'glance-manage.conf') conf_filepath = os.path.join(conf_dir, 'glance-manage.conf')
with open(conf_filepath, 'wb') as conf_file: with open(conf_filepath, 'w') as conf_file:
conf_file.write('[DEFAULT]\n') conf_file.write('[DEFAULT]\n')
conf_file.write('sql_connection = %s' % self.sql_connection) conf_file.write('sql_connection = %s' % self.sql_connection)
conf_file.flush() conf_file.flush()

View File

@ -14,6 +14,8 @@
import uuid import uuid
import six
import glance.artifacts as ga import glance.artifacts as ga
from glance.common import exception as exc from glance.common import exception as exc
from glance import context from glance import context
@ -513,7 +515,7 @@ class ArtifactTests(object):
self.assertIsNotNone(res['published_at']) self.assertIsNotNone(res['published_at'])
published_at = res['published_at'] published_at = res['published_at']
expected['published_at'] = published_at expected['published_at'] = published_at
for key, value in expected.iteritems(): for key, value in six.iteritems(expected):
self.assertEqual(expected[key], res[key]) self.assertEqual(expected[key], res[key])
def test_artifact_get_all(self): def test_artifact_get_all(self):

View File

@ -16,11 +16,11 @@
import json import json
import mock import mock
import os import os
import StringIO
import glance_store import glance_store
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_config import cfg from oslo_config import cfg
import six
from glance.async.flows import convert from glance.async.flows import convert
from glance.async import taskflow_executor from glance.async import taskflow_executor
@ -147,7 +147,7 @@ class TestImportTask(test_utils.BaseTestCase):
return ("", None) return ("", None)
with mock.patch.object(script_utils, 'get_image_data_iter') as dmock: with mock.patch.object(script_utils, 'get_image_data_iter') as dmock:
dmock.return_value = StringIO.StringIO("TEST_IMAGE") dmock.return_value = six.BytesIO("TEST_IMAGE")
with mock.patch.object(processutils, 'execute') as exc_mock: with mock.patch.object(processutils, 'execute') as exc_mock:
exc_mock.side_effect = fake_execute exc_mock.side_effect = fake_execute

View File

@ -529,7 +529,7 @@ class TestHelpers(test_utils.BaseTestCase):
'properties': {'distro': 'Ubuntu 10.04 LTS'}} 'properties': {'distro': 'Ubuntu 10.04 LTS'}}
headers = utils.image_meta_to_http_headers(fixture) headers = utils.image_meta_to_http_headers(fixture)
for k, v in six.iteritems(headers): for k, v in six.iteritems(headers):
self.assertIsInstance(v, unicode) self.assertIsInstance(v, six.text_type)
def test_data_passed_properly_through_headers(self): def test_data_passed_properly_through_headers(self):
""" """

View File

@ -108,7 +108,8 @@ class FakeHTTPConnection(object):
def getresponse(self): def getresponse(self):
class FakeResponse(object): class FakeResponse(object):
def __init__(self, (code, body, headers)): def __init__(self, args):
(code, body, headers) = args
self.body = six.StringIO(body) self.body = six.StringIO(body)
self.headers = headers self.headers = headers
self.status = code self.status = code

View File

@ -26,7 +26,6 @@ if possible.
from __future__ import print_function from __future__ import print_function
import datetime import datetime
import exceptions
import os import os
import pickle import pickle
import uuid import uuid
@ -420,7 +419,7 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
invalid_scheme_uri = ('http://acct:usr:pass@example.com' invalid_scheme_uri = ('http://acct:usr:pass@example.com'
'/container/obj-id') '/container/obj-id')
self.assertRaises(exceptions.AssertionError, self.assertRaises(AssertionError,
legacy_parse_uri_fn, legacy_parse_uri_fn,
invalid_scheme_uri, invalid_scheme_uri,
True) True)

View File

@ -1101,7 +1101,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
req = webob.Request.blank("/images") req = webob.Request.blank("/images")
req.headers['Content-Type'] = 'application/octet-stream' req.headers['Content-Type'] = 'application/octet-stream'
req.method = 'POST' req.method = 'POST'
for k, v in fixture_headers.iteritems(): for k, v in six.iteritems(fixture_headers):
req.headers[k] = v req.headers[k] = v
res = req.get_response(self.api) res = req.get_response(self.api)
self.assertEqual(400, res.status_int) self.assertEqual(400, res.status_int)
@ -1117,7 +1117,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
req = webob.Request.blank("/images") req = webob.Request.blank("/images")
req.headers['Content-Type'] = 'application/octet-stream' req.headers['Content-Type'] = 'application/octet-stream'
req.method = 'POST' req.method = 'POST'
for k, v in fixture_headers.iteritems(): for k, v in six.iteritems(fixture_headers):
req.headers[k] = v req.headers[k] = v
res = req.get_response(self.api) res = req.get_response(self.api)
self.assertEqual(400, res.status_int) self.assertEqual(400, res.status_int)
@ -1131,7 +1131,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
req = webob.Request.blank("/images") req = webob.Request.blank("/images")
req.headers['Content-Type'] = 'application/octet-stream' req.headers['Content-Type'] = 'application/octet-stream'
req.method = 'POST' req.method = 'POST'
for k, v in fixture_headers.iteritems(): for k, v in six.iteritems(fixture_headers):
req.headers[k] = v req.headers[k] = v
res = req.get_response(self.api) res = req.get_response(self.api)
self.assertEqual(400, res.status_int) self.assertEqual(400, res.status_int)
@ -1751,7 +1751,7 @@ class TestGlanceAPI(base.IsolatedUnitTest):
req = webob.Request.blank("/images") req = webob.Request.blank("/images")
req.method = 'POST' req.method = 'POST'
for k, v in fixture_headers.iteritems(): for k, v in six.iteritems(fixture_headers):
req.headers[k] = v req.headers[k] = v
res = req.get_response(self.api) res = req.get_response(self.api)