Remove six and python 2.7 full support

Six is in use to help us to keep support for python 2.7.
Since the ussuri cycle we decide to remove the python 2.7
support so we can go ahead and also remove six usage from
the python code.

Review process and help
-----------------------
Removing six introduce a lot of changes and an huge amount of modified files
To simplify reviews we decided to split changes into several patches to avoid
painful reviews and avoid mistakes.

To review this patch you can use the six documentation [1] to obtain help and
understand choices.

Additional informations
-----------------------
Changes related to 'six.b(data)' [2]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

six.b [2] encode the given datas in latin-1 in python3 so I did the same
things in this patch.

Latin-1 is equal to iso-8859-1 [3].

This encoding is the default encoding [4] of certain descriptive HTTP
headers.

I suggest to keep latin-1 for the moment and to move to another encoding
in a follow-up patch if needed to move to most powerful encoding (utf8).

HTML4 support utf8 charset and utf8 is the default charset for HTML5 [5].

Note that this commit message is autogenerated and not necesserly contains
changes related to 'six.b'

[1] https://six.readthedocs.io/
[2] https://six.readthedocs.io/#six.b
[3] https://docs.python.org/3/library/codecs.html#standard-encodings
[4] https://www.w3schools.com/charsets/ref_html_8859.asp
[5] https://www.w3schools.com/html/html_charset.asp

Patch 3 of a serie of 28 patches

Change-Id: If6e66839c128dde5fb80d90155dedb598da8d53b
This commit is contained in:
Hervé Beraud 2019-11-20 19:37:26 +01:00
parent bb02b2b5f1
commit fccd312871
16 changed files with 27 additions and 70 deletions

View File

@ -21,8 +21,6 @@ import sys
from oslo_log import log as logging
from oslo_utils import excutils
import six
from heat.common.i18n import _
_FATAL_EXCEPTION_FORMAT_ERRORS = False
@ -38,7 +36,6 @@ ERROR_CODE_MAP = {
}
@six.python_2_unicode_compatible
class HeatException(Exception):
"""Base Heat Exception.
@ -71,7 +68,7 @@ class HeatException(Exception):
# kwargs doesn't match a variable in the message
# log the issue and the kwargs
LOG.exception('Exception in string format operation')
for name, value in six.iteritems(kwargs):
for name, value in kwargs.items():
LOG.error("%(name)s: %(value)s",
{'name': name, 'value': value}) # noqa
@ -222,7 +219,7 @@ class HeatExceptionWithPath(HeatException):
if path is not None:
if isinstance(path, list):
self.path = path
elif isinstance(path, six.string_types):
elif isinstance(path, str):
self.path = [path]
result_path = ''
@ -247,7 +244,7 @@ class StackValidationFailed(HeatExceptionWithPath):
resource=None):
if path is None:
path = []
elif isinstance(path, six.string_types):
elif isinstance(path, str):
path = [path]
if resource is not None and not path:
@ -263,8 +260,8 @@ class StackValidationFailed(HeatExceptionWithPath):
# oslo.messaging.
self.args = error.args
else:
str_error = six.text_type(type(error).__name__)
message = six.text_type(error)
str_error = str(type(error).__name__)
message = str(error)
else:
str_error = error
@ -331,8 +328,8 @@ class ResourceFailure(HeatExceptionWithPath):
path = exception_or_error.path
else:
self.exc = exception_or_error
error = six.text_type(type(self.exc).__name__)
message = six.text_type(self.exc)
error = str(type(self.exc).__name__)
message = str(self.exc)
path = res_path
else:
self.exc = None
@ -418,7 +415,7 @@ class UpdateReplace(Exception):
"""Raised when resource update requires replacement."""
def __init__(self, resource_name='Unknown'):
msg = _("The Resource %s requires replacement.") % resource_name
super(Exception, self).__init__(six.text_type(msg))
super(Exception, self).__init__(str(msg))
class ResourceUnknownStatus(HeatException):
@ -443,7 +440,7 @@ class ResourceInError(HeatException):
class UpdateInProgress(Exception):
def __init__(self, resource_name='Unknown'):
msg = _("The resource %s is already being updated.") % resource_name
super(Exception, self).__init__(six.text_type(msg))
super(Exception, self).__init__(str(msg))
class HTTPExceptionDisguise(Exception):

View File

@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.common import exception
from heat.common.i18n import _
from heat.engine import status
@ -122,7 +120,7 @@ def get_members(group, include_failed=False):
"""
resources = []
if group.nested():
resources = [r for r in six.itervalues(group.nested())
resources = [r for r in group.nested().values()
if include_failed or r.status != r.FAILED]
return sorted(resources,

View File

@ -17,29 +17,10 @@
# recommendations from
# https://docs.openstack.org/oslo.i18n/latest/user/usage.html
import six
import oslo_i18n as i18n
from oslo_utils import encodeutils
_translators = i18n.TranslatorFactory(domain='heat')
# The primary translation function using the well-known name "_"
_ = _translators.primary
def repr_wrapper(klass):
"""A decorator that defines __repr__ method under Python 2.
Under Python 2 it will encode repr return value to str type.
Under Python 3 it does nothing.
"""
if six.PY2:
if '__repr__' not in klass.__dict__:
raise ValueError("@repr_wrapper cannot be applied "
"to %s because it doesn't define __repr__()." %
klass.__name__)
klass._repr = klass.__repr__
klass.__repr__ = lambda self: encodeutils.safe_encode(self._repr())
return klass

View File

@ -15,7 +15,7 @@ import collections
import re
from oslo_utils import encodeutils
from six.moves.urllib import parse as urlparse
from urllib import parse as urlparse
from heat.common.i18n import _

View File

@ -12,11 +12,10 @@
# under the License.
import collections
import io
import random as random_module
import string
import six
# NOTE(pas-ha) Heat officially supports only POSIX::Linux platform
# where os.urandom() and random.SystemRandom() are available
@ -88,19 +87,19 @@ def generate_password(length, char_classes):
:param char_classes: Iterable over classes of characters from which to
generate a password
"""
char_buffer = six.StringIO()
char_buffer = io.StringIO()
all_allowed_chars = set()
# Add the minimum number of chars from each char class
for char_class in char_classes:
all_allowed_chars |= char_class.allowed_chars
allowed_chars = tuple(char_class.allowed_chars)
for i in six.moves.xrange(char_class.min_count):
for i in range(char_class.min_count):
char_buffer.write(random.choice(allowed_chars))
# Fill up rest with random chars from provided classes
combined_chars = tuple(all_allowed_chars)
for i in six.moves.xrange(max(0, length - char_buffer.tell())):
for i in range(max(0, length - char_buffer.tell())):
char_buffer.write(random.choice(combined_chars))
# Shuffle string

View File

@ -19,12 +19,12 @@ existing package tree, use create_subpackage() to dynamically create a package
for them before loading them.
"""
import functools
import pkgutil
import sys
import types
from oslo_log import log as logging
import six
LOG = logging.getLogger(__name__)
@ -46,7 +46,7 @@ def create_subpackage(path, parent_package_name, subpackage_name="plugins"):
package_name = _module_name(parent_package_name, subpackage_name)
package = types.ModuleType(package_name)
package.__path__ = ([path] if isinstance(path, six.string_types)
package.__path__ = ([path] if isinstance(path, str)
else list(path))
sys.modules[package_name] = package
@ -75,7 +75,7 @@ def _import_module(importer, module_name, package):
# Make this accessible through the parent package for static imports
local_name = module_name.partition(package.__name__ + '.')[2]
module_components = local_name.split('.')
parent = six.moves.reduce(getattr, module_components[:-1], package)
parent = functools.reduce(getattr, module_components[:-1], package)
setattr(parent, module_components[-1], module)
return module

View File

@ -12,7 +12,6 @@
# under the License.
from oslo_log import log as logging
import six
LOG = logging.getLogger(__name__)
@ -23,5 +22,5 @@ def log_fail_msg(manager, entrypoint, exception):
'"%(message)s". Not using %(name)s.',
{'module_name': entrypoint.module_name,
'message': getattr(exception, 'message',
six.text_type(exception)),
str(exception)),
'name': entrypoint.name})

View File

@ -21,7 +21,6 @@ from oslo_config import cfg
from oslo_log import log as logging
from oslo_policy import policy
from oslo_utils import excutils
import six
from heat.common import exception
from heat.common.i18n import _
@ -151,7 +150,7 @@ class ResourceEnforcer(Enforcer):
except policy.PolicyNotRegistered:
result = True
except self.exc as ex:
LOG.info(six.text_type(ex))
LOG.info(str(ex))
raise
if not result:
if self.exc:

View File

@ -23,7 +23,6 @@ import datetime
from lxml import etree
from oslo_log import log as logging
from oslo_serialization import jsonutils
import six
LOG = logging.getLogger(__name__)
@ -34,7 +33,7 @@ class JSONResponseSerializer(object):
def sanitizer(obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
return six.text_type(obj)
return str(obj)
response = jsonutils.dumps(data, default=sanitizer)
@ -46,7 +45,7 @@ class JSONResponseSerializer(object):
def default(self, response, result):
response.content_type = 'application/json'
response.body = six.b(self.to_json(result))
response.body = self.to_json(result).encode('latin-1')
# Escape XML serialization for these keys, as the AWS API defines them as
@ -75,11 +74,11 @@ class XMLResponseSerializer(object):
else:
self.object_to_element(value, subelement)
else:
element.text = six.text_type(obj)
element.text = str(obj)
def to_xml(self, data):
# Assumption : root node is dict with single key
root = next(six.iterkeys(data))
root = next(iter(data.keys()))
eltree = etree.Element(root)
self.object_to_element(data.get(root), eltree)
response = etree.tostring(eltree)

View File

@ -19,8 +19,6 @@ The IDs each comprise 12 (lower-case) alphanumeric characters.
import base64
import uuid
import six
from heat.common.i18n import _
@ -30,12 +28,12 @@ def _to_byte_string(value, num_bits):
Padding is added at the end (i.e. after the least-significant bit) if
required.
"""
shifts = six.moves.xrange(num_bits - 8, -8, -8)
shifts = range(num_bits - 8, -8, -8)
def byte_at(off):
return (value >> off if off >= 0 else value << -off) & 0xff
return b''.join(six.int2byte(byte_at(offset)) for offset in shifts)
return b''.join(bytes((byte_at(offset),)) for offset in shifts)
def get_id(source_uuid):
@ -43,7 +41,7 @@ def get_id(source_uuid):
The supplied UUID must be a version 4 UUID object.
"""
if isinstance(source_uuid, six.string_types):
if isinstance(source_uuid, str):
source_uuid = uuid.UUID(source_uuid)
if source_uuid.version != 4:
raise ValueError(_('Invalid UUID version (%d)') % source_uuid.version)

View File

@ -17,7 +17,6 @@ from oslo_utils import strutils
import six
from heat.common.i18n import _
from heat.common.i18n import repr_wrapper
from heat.engine import constraints as constr
from heat.engine import support
@ -139,7 +138,6 @@ BASE_ATTRIBUTES = (SHOW_ATTR, ) = ('show', )
ALL_ATTRIBUTES = '*'
@repr_wrapper
class Attributes(collections.Mapping):
"""Models a collection of Resource Attributes."""

View File

@ -18,14 +18,12 @@ import six
from heat.common import exception
from heat.common.i18n import _
from heat.common.i18n import repr_wrapper
class CircularDependencyException(exception.HeatException):
msg_fmt = _("Circular Dependency Found: %(cycle)s")
@repr_wrapper
@six.python_2_unicode_compatible
class Node(object):
"""A node in a dependency graph."""
@ -172,7 +170,6 @@ class Graph(collections.defaultdict):
raise CircularDependencyException(cycle=six.text_type(graph))
@repr_wrapper
@six.python_2_unicode_compatible
class Dependencies(object):
"""Helper class for calculating a dependency graph."""

View File

@ -18,7 +18,6 @@ import operator
import six
from heat.common import exception
from heat.common.i18n import repr_wrapper
from heat.engine import function
from heat.engine import properties
@ -37,7 +36,6 @@ FIELDS = (
)
@repr_wrapper
class ResourceDefinition(object):
"""A definition of a resource, independent of any template format."""

View File

@ -21,7 +21,6 @@ from oslo_utils import excutils
import six
from heat.common.i18n import _
from heat.common.i18n import repr_wrapper
from heat.common import timeutils
LOG = logging.getLogger(__name__)
@ -365,7 +364,6 @@ def wrappertask(task): # noqa: C901
return wrapper
@repr_wrapper
class DependencyTaskGroup(object):
"""Task which manages group of subtasks that have ordering dependencies."""

View File

@ -15,7 +15,6 @@ from oslo_log import log as logging
import six
from heat.common import exception
from heat.common.i18n import repr_wrapper
from heat.engine import dependencies
from heat.engine import resource
from heat.engine import scheduler
@ -25,7 +24,6 @@ from heat.objects import resource as resource_objects
LOG = logging.getLogger(__name__)
@repr_wrapper
class StackUpdate(object):
"""A Task to perform the update of an existing stack to a new template."""

View File

@ -18,7 +18,6 @@ import eventlet
import mock
import six
from heat.common.i18n import repr_wrapper
from heat.common import timeutils
from heat.engine import dependencies
from heat.engine import scheduler
@ -1273,7 +1272,6 @@ class DescriptionTest(common.HeatTestCase):
self.assertEqual('o', scheduler.task_description(C()))
def test_unicode(self):
@repr_wrapper
@six.python_2_unicode_compatible
class C(object):
def __str__(self):