From 7cecdfeccba20a29f7248971c81d90d04e575d66 Mon Sep 17 00:00:00 2001 From: Tom Cammann Date: Fri, 26 Jun 2015 14:36:37 +0100 Subject: [PATCH] Upgrade code to be python 3 compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Various py2 to py3 fixes: 1. func.im_self to func.__self__ 2. func.func_name to func.__name__ 3. basestring to six.string_types 4. unicode to six.u 5. use bytes where appropriate instead of str 6. convert bytes to string for use with re 7. update usage of dict.keys() 8. update regex match for dealing with unicode characters, as '\w' matches unicode word characters in python 3 such as 的. References: [1] http://www.diveintopython3.net/porting-code-to-python-3-with-2to3.html#methodattrs [2] https://docs.python.org/3/whatsnew/3.0.html#operators-and-special-methods [3][4][5][6] https://docs.python.org/3.0/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit [7] https://docs.python.org/3.0/whatsnew/3.0.html#views-and-iterators-instead-of-lists [8] https://docs.python.org/3/library/re.html#regular-expression-syntax Partially-Implements: blueprint magnum-python3 Change-Id: I6a7e13feeecd66910f2046956b1edc4d871208f6 --- magnum/common/policy.py | 2 +- magnum/common/safe_utils.py | 6 +++--- magnum/common/short_id.py | 2 +- magnum/common/utils.py | 7 +++---- magnum/conductor/handlers/docker_conductor.py | 3 ++- magnum/tests/unit/common/test_utils.py | 4 ++-- magnum/tests/unit/objects/test_objects.py | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/magnum/common/policy.py b/magnum/common/policy.py index 7258002377..b5751107a3 100644 --- a/magnum/common/policy.py +++ b/magnum/common/policy.py @@ -109,7 +109,7 @@ def enforce_wsgi(api_name, act=None): ... """ def wraper(fn): - action = "%s:%s" % (api_name, (act or fn.func_name)) + action = "%s:%s" % (api_name, (act or fn.__name__)) @functools.wraps(fn) def handle(self, *args, **kwargs): diff --git a/magnum/common/safe_utils.py b/magnum/common/safe_utils.py index 7f03fd6796..30e19485ab 100644 --- a/magnum/common/safe_utils.py +++ b/magnum/common/safe_utils.py @@ -36,10 +36,10 @@ def getcallargs(function, *args, **kwargs): # argnames but not in args or kwargs. Uses 'in' rather than '==' because # some tests use 'self2'. if 'self' in argnames[0] or 'cls' == argnames[0]: - # The function may not actually be a method or have im_self. + # The function may not actually be a method or have __self__. # Typically seen when it's stubbed with mox. - if inspect.ismethod(function) and hasattr(function, 'im_self'): - keyed_args[argnames[0]] = function.im_self + if inspect.ismethod(function) and hasattr(function, '__self__'): + keyed_args[argnames[0]] = function.__self__ else: keyed_args[argnames[0]] = None diff --git a/magnum/common/short_id.py b/magnum/common/short_id.py index b8de14d6f2..03dbd8d360 100644 --- a/magnum/common/short_id.py +++ b/magnum/common/short_id.py @@ -49,7 +49,7 @@ def get_id(source_uuid): # (see RFC4122, Section 4.4) random_bytes = _to_byte_string(source_uuid.time, 60) # The first 12 bytes (= 60 bits) of base32-encoded output is our data - encoded = base64.b32encode(random_bytes)[:12] + encoded = base64.b32encode(six.b(random_bytes))[:12] return encoded.lower() diff --git a/magnum/common/utils.py b/magnum/common/utils.py index cec6e13eb3..3f55553b17 100644 --- a/magnum/common/utils.py +++ b/magnum/common/utils.py @@ -281,11 +281,10 @@ def convert_to_list_dict(lst, label): def sanitize_hostname(hostname): """Return a hostname which conforms to RFC-952 and RFC-1123 specs.""" - if isinstance(hostname, six.text_type): - hostname = hostname.encode('latin-1', 'ignore') + hostname = six.text_type(hostname) hostname = re.sub('[ _]', '-', hostname) - hostname = re.sub('[^\w.-]+', '', hostname) + hostname = re.sub('[^a-zA-Z0-9_.-]+', '', hostname) hostname = hostname.lower() hostname = hostname.strip('.-') @@ -564,7 +563,7 @@ def is_name_safe(name): def raise_exception_invalid_scheme(url): valid_schemes = ['http', 'https'] - if not isinstance(url, basestring): + if not isinstance(url, six.string_types): raise exception.Urllib2InvalidScheme(url=url) scheme = url.split(':')[0] diff --git a/magnum/conductor/handlers/docker_conductor.py b/magnum/conductor/handlers/docker_conductor.py index 1882fc22ea..5b349e6ab0 100644 --- a/magnum/conductor/handlers/docker_conductor.py +++ b/magnum/conductor/handlers/docker_conductor.py @@ -16,6 +16,7 @@ from docker import errors import functools from oslo_config import cfg from oslo_log import log as logging +import six from magnum.common import docker_utils from magnum.common import exception @@ -87,7 +88,7 @@ class Handler(object): return {} def _encode_utf8(self, value): - return unicode(value).encode('utf-8') + return six.u(value).encode('utf-8') @staticmethod def _docker_for_bay(bay): diff --git a/magnum/tests/unit/common/test_utils.py b/magnum/tests/unit/common/test_utils.py index 5bd39fd975..25dc7d67e9 100644 --- a/magnum/tests/unit/common/test_utils.py +++ b/magnum/tests/unit/common/test_utils.py @@ -160,7 +160,7 @@ exit 1 self.assertRaises(processutils.ProcessExecutionError, utils.execute, tmpfilename, tmpfilename2, attempts=10, - process_input='foo', + process_input=b'foo', delay_on_retry=False) except OSError as e: if e.errno == errno.EACCES: @@ -211,7 +211,7 @@ grep foo try: utils.execute(tmpfilename, tmpfilename2, - process_input='foo', + process_input=b'foo', attempts=2) except OSError as e: if e.errno == errno.EACCES: diff --git a/magnum/tests/unit/objects/test_objects.py b/magnum/tests/unit/objects/test_objects.py index 40a49b970c..7610b43965 100644 --- a/magnum/tests/unit/objects/test_objects.py +++ b/magnum/tests/unit/objects/test_objects.py @@ -373,7 +373,7 @@ class _TestObject(object): self.assertRaises(AttributeError, obj.get, 'nothing', 3) def test_object_inheritance(self): - base_fields = base.MagnumObject.fields.keys() + base_fields = list(base.MagnumObject.fields.keys()) myobj_fields = ['foo', 'bar', 'missing'] + base_fields myobj3_fields = ['new_field'] self.assertTrue(issubclass(TestSubclassedObject, MyObj))