Upgrade code to be python 3 compatible

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
This commit is contained in:
Tom Cammann 2015-06-26 14:36:37 +01:00
parent 6e6af73789
commit 7cecdfeccb
7 changed files with 13 additions and 13 deletions

View File

@ -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):

View File

@ -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

View File

@ -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()

View File

@ -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]

View File

@ -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):

View File

@ -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:

View File

@ -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))