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 6 of a serie of 28 patches

Change-Id: Ic56cf6da5ff9ab8f4bd218e6516b87f47165206d
This commit is contained in:
Hervé Beraud 2019-11-20 19:37:26 +01:00
parent 6ccd16cc32
commit 8c0d58075b
10 changed files with 134 additions and 163 deletions

View File

@ -14,8 +14,6 @@
import collections
import itertools
import six
from heat.common import exception
from heat.common.i18n import _
@ -24,7 +22,6 @@ class CircularDependencyException(exception.HeatException):
msg_fmt = _("Circular Dependency Found: %(cycle)s")
@six.python_2_unicode_compatible
class Node(object):
"""A node in a dependency graph."""
@ -92,15 +89,14 @@ class Node(object):
def __str__(self):
"""Return a human-readable string representation of the node."""
text = '{%s}' % ', '.join(six.text_type(n) for n in self)
return six.text_type(text)
text = '{%s}' % ', '.join(str(n) for n in self)
return str(text)
def __repr__(self):
"""Return a string representation of the node."""
return repr(self.require)
@six.python_2_unicode_compatible
class Graph(collections.defaultdict):
"""A mutable mapping of objects to nodes in a dependency graph."""
@ -132,7 +128,7 @@ class Graph(collections.defaultdict):
for rqd in node:
yield (rqr, rqd)
return itertools.chain.from_iterable(outgoing_edges(*i)
for i in six.iteritems(self))
for i in self.items())
def __delitem__(self, key):
"""Delete the node given by the specified key from the graph."""
@ -147,10 +143,10 @@ class Graph(collections.defaultdict):
def __str__(self):
"""Convert the graph to a human-readable string."""
pairs = ('%s: %s' % (six.text_type(k), six.text_type(v))
for k, v in six.iteritems(self))
pairs = ('%s: %s' % (str(k), str(v))
for k, v in self.items())
text = '{%s}' % ', '.join(pairs)
return six.text_type(text)
return str(text)
@staticmethod
def toposort(graph):
@ -158,8 +154,8 @@ class Graph(collections.defaultdict):
This is a destructive operation for the graph.
"""
for iteration in six.moves.xrange(len(graph)):
for key, node in six.iteritems(graph):
for iteration in range(len(graph)):
for key, node in graph.items():
if not node:
yield key
del graph[key]
@ -167,10 +163,9 @@ class Graph(collections.defaultdict):
else:
# There are nodes remaining, but none without
# dependencies: a cycle
raise CircularDependencyException(cycle=six.text_type(graph))
raise CircularDependencyException(cycle=str(graph))
@six.python_2_unicode_compatible
class Dependencies(object):
"""Helper class for calculating a dependency graph."""
@ -227,8 +222,8 @@ class Dependencies(object):
return itertools.chain([(rqr, key)], get_edges(rqr))
# Get the edge list for each node that requires the current node
edge_lists = six.moves.map(requirer_edges,
self._graph[key].required_by())
edge_lists = map(requirer_edges,
self._graph[key].required_by())
# Combine the lists into one long list
return itertools.chain.from_iterable(edge_lists)
@ -263,7 +258,7 @@ class Dependencies(object):
def __str__(self):
"""Return a human-readable string repr of the dependency graph."""
return six.text_type(self._graph)
return str(self._graph)
def __repr__(self):
"""Return a consistent string representation of the object."""

View File

@ -21,7 +21,6 @@ import weakref
from oslo_config import cfg
from oslo_log import log
from oslo_utils import fnmatch
import six
from heat.common import environment_format as env_fmt
from heat.common import exception
@ -54,7 +53,7 @@ def valid_restricted_actions(action):
def is_hook_definition(key, value):
is_valid_hook = False
if key == 'hooks':
if isinstance(value, six.string_types):
if isinstance(value, str):
is_valid_hook = valid_hook_type(value)
elif isinstance(value, collections.Sequence):
is_valid_hook = all(valid_hook_type(hook) for hook in value)
@ -71,7 +70,7 @@ def is_hook_definition(key, value):
def is_valid_restricted_action(key, value):
valid_action = False
if key == 'restricted_actions':
if isinstance(value, six.string_types):
if isinstance(value, str):
valid_action = valid_restricted_actions(value)
elif isinstance(value, collections.Sequence):
valid_action = all(valid_restricted_actions(
@ -101,7 +100,7 @@ class ResourceInfo(object):
if name.endswith(('.yaml', '.template')):
# a template url for the resource "Type"
klass = TemplateResourceInfo
elif not isinstance(value, six.string_types):
elif not isinstance(value, str):
klass = ClassResourceInfo
elif value.endswith(('.yaml', '.template')):
# a registered template
@ -344,10 +343,8 @@ class ResourceRegistry(object):
if info.value.support_status.message is not None:
details = {
'name': info.name,
'status': six.text_type(
info.value.support_status.status),
'message': six.text_type(
info.value.support_status.message)
'status': str(info.value.support_status.status),
'message': str(info.value.support_status.message)
}
LOG.warning('%(name)s is %(status)s. %(message)s',
details)
@ -364,7 +361,7 @@ class ResourceRegistry(object):
if show_all or isinstance(registry[name], TemplateResourceInfo):
msg = ('%(p)sRegistered: %(t)s' %
{'p': prefix,
't': six.text_type(registry[name])})
't': str(registry[name])})
LOG.info(msg)
def remove_item(self, info):
@ -394,11 +391,11 @@ class ResourceRegistry(object):
"""
ress = self._registry['resources']
restricted_actions = set()
for name_pattern, resource in six.iteritems(ress):
for name_pattern, resource in ress.items():
if fnmatch.fnmatchcase(resource_name, name_pattern):
if 'restricted_actions' in resource:
actions = resource['restricted_actions']
if isinstance(actions, six.string_types):
if isinstance(actions, str):
restricted_actions.add(actions)
elif isinstance(actions, collections.Sequence):
restricted_actions |= set(actions)
@ -429,11 +426,11 @@ class ResourceRegistry(object):
everything.
"""
ress = self._registry['resources']
for name_pattern, resource in six.iteritems(ress):
for name_pattern, resource in ress.items():
if fnmatch.fnmatchcase(resource_name, name_pattern):
if 'hooks' in resource:
hooks = resource['hooks']
if isinstance(hooks, six.string_types):
if isinstance(hooks, str):
if hook == hooks:
return True
elif isinstance(hooks, collections.Sequence):
@ -444,7 +441,7 @@ class ResourceRegistry(object):
def remove_resources_except(self, resource_name):
ress = self._registry['resources']
new_resources = {}
for name, res in six.iteritems(ress):
for name, res in ress.items():
if fnmatch.fnmatchcase(resource_name, name):
new_resources.update(res)
if resource_name in ress:
@ -477,7 +474,7 @@ class ResourceRegistry(object):
# handle: "OS::*" -> "Dreamhost::*"
def is_a_glob(resource_type):
return resource_type.endswith('*')
globs = six.moves.filter(is_a_glob, iter(self._registry))
globs = filter(is_a_glob, iter(self._registry))
for pattern in globs:
if self._registry[pattern].matches(resource_type):
yield self._registry[pattern]
@ -550,7 +547,7 @@ class ResourceRegistry(object):
msg = _('Non-empty resource type is required '
'for resource "%s"') % resource_name
raise exception.StackValidationFailed(message=msg)
elif not isinstance(resource_type, six.string_types):
elif not isinstance(resource_type, str):
msg = _('Resource "%s" type is not a string') % resource_name
raise exception.StackValidationFailed(message=msg)
@ -558,7 +555,7 @@ class ResourceRegistry(object):
info = self.get_resource_info(resource_type,
resource_name=resource_name)
except exception.EntityNotFound as exc:
raise exception.StackValidationFailed(message=six.text_type(exc))
raise exception.StackValidationFailed(message=str(exc))
return info.get_class_to_instantiate()
@ -590,7 +587,7 @@ class ResourceRegistry(object):
if support_status is not None and not support.is_valid_status(
support_status):
msg = (_('Invalid support status and should be one of %s') %
six.text_type(support.SUPPORT_STATUSES))
str(support.SUPPORT_STATUSES))
raise exception.Invalid(reason=msg)
def is_resource(key):
@ -650,7 +647,7 @@ class ResourceRegistry(object):
}
return [resource_description(name, cls, with_description)
for name, cls in six.iteritems(self._registry)
for name, cls in self._registry.items()
if (is_resource(name) and
name_matches(name) and
status_matches(cls) and
@ -693,7 +690,7 @@ class Environment(object):
if env_fmt.PARAMETERS in env:
self.params = env[env_fmt.PARAMETERS]
else:
self.params = dict((k, v) for (k, v) in six.iteritems(env)
self.params = dict((k, v) for (k, v) in env.items()
if k not in (env_fmt.PARAMETER_DEFAULTS,
env_fmt.ENCRYPTED_PARAM_NAMES,
env_fmt.EVENT_SINKS,

View File

@ -16,14 +16,11 @@ import collections
import itertools
import weakref
import six
from heat.common import exception
from heat.common.i18n import _
@six.add_metaclass(abc.ABCMeta)
class Function(object):
class Function(metaclass=abc.ABCMeta):
"""Abstract base class for template functions."""
def __init__(self, stack, fn_name, args):
@ -98,13 +95,13 @@ class Function(object):
return all_dep_attrs(self.args)
def res_dep_attrs(resource_name):
return six.moves.zip(itertools.repeat(resource_name),
self.dep_attrs(resource_name))
return zip(itertools.repeat(resource_name),
self.dep_attrs(resource_name))
resource_names = self.stack.enabled_rsrc_names()
return itertools.chain.from_iterable(six.moves.map(res_dep_attrs,
resource_names))
return itertools.chain.from_iterable(map(res_dep_attrs,
resource_names))
def __reduce__(self):
"""Return a representation of the function suitable for pickling.
@ -160,8 +157,7 @@ class Function(object):
__hash__ = None
@six.add_metaclass(abc.ABCMeta)
class Macro(Function):
class Macro(Function, metaclass=abc.ABCMeta):
"""Abstract base class for template macros.
A macro differs from a function in that it controls how the template is
@ -260,7 +256,7 @@ def resolve(snippet):
if isinstance(snippet, collections.Mapping):
return dict((k, resolve(v)) for k, v in snippet.items())
elif (not isinstance(snippet, six.string_types) and
elif (not isinstance(snippet, str) and
isinstance(snippet, collections.Iterable)):
return [resolve(v) for v in snippet]
@ -270,7 +266,7 @@ def resolve(snippet):
def validate(snippet, path=None):
if path is None:
path = []
elif isinstance(path, six.string_types):
elif isinstance(path, str):
path = [path]
if isinstance(snippet, Function):
@ -281,11 +277,11 @@ def validate(snippet, path=None):
except Exception as e:
raise exception.StackValidationFailed(
path=path + [snippet.fn_name],
message=six.text_type(e))
message=str(e))
elif isinstance(snippet, collections.Mapping):
for k, v in six.iteritems(snippet):
for k, v in snippet.items():
validate(v, path + [k])
elif (not isinstance(snippet, six.string_types) and
elif (not isinstance(snippet, str) and
isinstance(snippet, collections.Iterable)):
basepath = list(path)
parent = basepath.pop() if basepath else ''
@ -305,13 +301,13 @@ def dependencies(snippet, path=''):
elif isinstance(snippet, collections.Mapping):
def mkpath(key):
return '.'.join([path, six.text_type(key)])
return '.'.join([path, str(key)])
deps = (dependencies(value,
mkpath(key)) for key, value in snippet.items())
return itertools.chain.from_iterable(deps)
elif (not isinstance(snippet, six.string_types) and
elif (not isinstance(snippet, str) and
isinstance(snippet, collections.Iterable)):
def mkpath(idx):
return ''.join([path, '[%d]' % idx])
@ -340,7 +336,7 @@ def dep_attrs(snippet, resource_name):
elif isinstance(snippet, collections.Mapping):
attrs = (dep_attrs(val, resource_name) for val in snippet.values())
return itertools.chain.from_iterable(attrs)
elif (not isinstance(snippet, six.string_types) and
elif (not isinstance(snippet, str) and
isinstance(snippet, collections.Iterable)):
attrs = (dep_attrs(value, resource_name) for value in snippet)
return itertools.chain.from_iterable(attrs)
@ -363,7 +359,7 @@ def all_dep_attrs(snippet):
elif isinstance(snippet, collections.Mapping):
res_attrs = (all_dep_attrs(value) for value in snippet.values())
return itertools.chain.from_iterable(res_attrs)
elif (not isinstance(snippet, six.string_types) and
elif (not isinstance(snippet, str) and
isinstance(snippet, collections.Iterable)):
res_attrs = (all_dep_attrs(value) for value in snippet)
return itertools.chain.from_iterable(res_attrs)

View File

@ -12,14 +12,14 @@
# under the License.
import collections
import functools
import hashlib
import itertools
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
import six
from six.moves.urllib import parse as urlparse
from urllib import parse as urlparse
import yaql
from yaql.language import exceptions
@ -76,7 +76,7 @@ class GetParam(function.Function):
raise ValueError(_('Function "%s" must have arguments') %
self.fn_name)
if isinstance(args, six.string_types):
if isinstance(args, str):
param_name = args
path_components = []
elif isinstance(args, collections.Sequence):
@ -86,7 +86,7 @@ class GetParam(function.Function):
raise TypeError(_('Argument to "%s" must be string or list') %
self.fn_name)
if not isinstance(param_name, six.string_types):
if not isinstance(param_name, str):
raise TypeError(_('Parameter name in "%s" must be string') %
self.fn_name)
@ -100,12 +100,12 @@ class GetParam(function.Function):
collections.Sequence)):
raise TypeError(_('"%s" can\'t traverse path') % self.fn_name)
if not isinstance(key, (six.string_types, int)):
if not isinstance(key, (str, int)):
raise TypeError(_('Path components in "%s" '
'must be strings') % self.fn_name)
if isinstance(collection, collections.Sequence
) and isinstance(key, six.string_types):
) and isinstance(key, str):
try:
key = int(key)
except ValueError:
@ -116,7 +116,7 @@ class GetParam(function.Function):
return collection[key]
try:
return six.moves.reduce(get_path_component, path_components,
return functools.reduce(get_path_component, path_components,
parameter)
except (KeyError, IndexError, TypeError):
return ''
@ -168,7 +168,7 @@ class GetAttThenSelect(function.Function):
def _parse_args(self):
if (not isinstance(self.args, collections.Sequence) or
isinstance(self.args, six.string_types)):
isinstance(self.args, str)):
raise TypeError(_('Argument to "%s" must be a list') %
self.fn_name)
@ -200,7 +200,7 @@ class GetAttThenSelect(function.Function):
attrs = [self._attr_path()]
except Exception as exc:
LOG.debug("Ignoring exception calculating required attributes"
": %s %s", type(exc).__name__, six.text_type(exc))
": %s %s", type(exc).__name__, str(exc))
attrs = []
else:
attrs = []
@ -400,13 +400,13 @@ class Replace(function.Function):
return ''
if not isinstance(value,
(six.string_types, six.integer_types,
(str, int,
float, bool)):
raise TypeError(_('"%(name)s" params must be strings or numbers, '
'param %(param)s is not valid') %
{'name': self.fn_name, 'param': param})
return six.text_type(value)
return str(value)
def result(self):
template = function.resolve(self._string)
@ -415,7 +415,7 @@ class Replace(function.Function):
if self._strict:
unreplaced_keys = set(mapping)
if not isinstance(template, six.string_types):
if not isinstance(template, str):
raise TypeError(_('"%s" template must be a string') % self.fn_name)
if not isinstance(mapping, collections.Mapping):
@ -426,7 +426,7 @@ class Replace(function.Function):
return strings
placeholder = keys[0]
if not isinstance(placeholder, six.string_types):
if not isinstance(placeholder, str):
raise TypeError(_('"%s" param placeholders must be strings') %
self.fn_name)
@ -490,7 +490,7 @@ class ReplaceJson(Replace):
else:
_raise_empty_param_value_error()
if not isinstance(value, (six.string_types, six.integer_types,
if not isinstance(value, (str, int,
float, bool)):
if isinstance(value, (collections.Mapping, collections.Sequence)):
if not self._allow_empty_value and len(value) == 0:
@ -507,7 +507,7 @@ class ReplaceJson(Replace):
raise TypeError(_('"%s" params must be strings, numbers, '
'list or map.') % self.fn_name)
ret_value = six.text_type(value)
ret_value = str(value)
if not self._allow_empty_value and not ret_value:
_raise_empty_param_value_error()
return ret_value
@ -553,7 +553,7 @@ class GetFile(function.Function):
assert self.files is not None, "No stack definition in Function"
args = function.resolve(self.args)
if not (isinstance(args, six.string_types)):
if not (isinstance(args, str)):
raise TypeError(_('Argument to "%s" must be a string') %
self.fn_name)
@ -603,19 +603,19 @@ class Join(function.Function):
strings = function.resolve(self._strings)
if strings is None:
strings = []
if (isinstance(strings, six.string_types) or
if (isinstance(strings, str) or
not isinstance(strings, collections.Sequence)):
raise TypeError(_('"%s" must operate on a list') % self.fn_name)
delim = function.resolve(self._delim)
if not isinstance(delim, six.string_types):
if not isinstance(delim, str):
raise TypeError(_('"%s" delimiter must be a string') %
self.fn_name)
def ensure_string(s):
if s is None:
return ''
if not isinstance(s, six.string_types):
if not isinstance(s, str):
raise TypeError(
_('Items to join must be strings not %s'
) % (repr(s)[:200]))
@ -668,7 +668,7 @@ class JoinMultiple(function.Function):
strings = []
for jl in r_joinlists:
if jl:
if (isinstance(jl, six.string_types) or
if (isinstance(jl, str) or
not isinstance(jl, collections.Sequence)):
raise TypeError(_('"%s" must operate on '
'a list') % self.fn_name)
@ -676,7 +676,7 @@ class JoinMultiple(function.Function):
strings += jl
delim = function.resolve(self._delim)
if not isinstance(delim, six.string_types):
if not isinstance(delim, str):
raise TypeError(_('"%s" delimiter must be a string') %
self.fn_name)
@ -685,7 +685,7 @@ class JoinMultiple(function.Function):
) % (repr(s)[:200])
if s is None:
return ''
elif isinstance(s, six.string_types):
elif isinstance(s, str):
return s
elif isinstance(s, (collections.Mapping, collections.Sequence)):
try:
@ -801,7 +801,7 @@ class MapReplace(function.Function):
repl_keys = ensure_map(repl_map.get('keys', {}))
repl_values = ensure_map(repl_map.get('values', {}))
ret_map = {}
for k, v in six.iteritems(in_map):
for k, v in in_map.items():
key = repl_keys.get(k)
if key is None:
key = k
@ -930,12 +930,12 @@ class Repeat(function.Function):
def _valid_arg(self, arg):
if not (isinstance(arg, (collections.Sequence,
function.Function)) and
not isinstance(arg, six.string_types)):
not isinstance(arg, str)):
raise TypeError(_('The values of the "for_each" argument to '
'"%s" must be lists') % self.fn_name)
def _do_replacement(self, keys, values, template):
if isinstance(template, six.string_types):
if isinstance(template, str):
for (key, value) in zip(keys, values):
template = template.replace(key, value)
return template
@ -951,7 +951,7 @@ class Repeat(function.Function):
def result(self):
for_each = function.resolve(self._for_each)
keys, lists = six.moves.zip(*for_each.items())
keys, lists = zip(*for_each.items())
# use empty list for references(None) else validation will fail
value_lens = []
@ -970,7 +970,7 @@ class Repeat(function.Function):
'loop.') % self.fn_name)
template = function.resolve(self._template)
iter_func = itertools.product if self._nested_loop else six.moves.zip
iter_func = itertools.product if self._nested_loop else zip
return [self._do_replacement(keys, replacements, template)
for replacements in iter_func(*values)]
@ -996,7 +996,7 @@ class RepeatWithMap(Repeat):
if not (isinstance(arg, (collections.Sequence,
collections.Mapping,
function.Function)) and
not isinstance(arg, six.string_types)):
not isinstance(arg, str)):
raise TypeError(_('The values of the "for_each" argument to '
'"%s" must be lists or maps') % self.fn_name)
@ -1067,7 +1067,7 @@ class Digest(function.Function):
def validate_usage(self, args):
if not (isinstance(args, list) and
all([isinstance(a, six.string_types) for a in args])):
all([isinstance(a, str) for a in args])):
msg = _('Argument to function "%s" must be a list of strings')
raise TypeError(msg % self.fn_name)
@ -1075,18 +1075,15 @@ class Digest(function.Function):
msg = _('Function "%s" usage: ["<algorithm>", "<value>"]')
raise ValueError(msg % self.fn_name)
if six.PY3:
algorithms = hashlib.algorithms_available
else:
algorithms = hashlib.algorithms
algorithms = hashlib.algorithms_available
if args[0].lower() not in algorithms:
msg = _('Algorithm must be one of %s')
raise ValueError(msg % six.text_type(algorithms))
raise ValueError(msg % str(algorithms))
def digest(self, algorithm, value):
_hash = hashlib.new(algorithm)
_hash.update(six.b(value))
_hash.update(value.encode('latin-1'))
return _hash.hexdigest()
@ -1121,7 +1118,7 @@ class StrSplit(function.Function):
'example': example}
self.fn_name = fn_name
if isinstance(args, (six.string_types, collections.Mapping)):
if isinstance(args, (str, collections.Mapping)):
raise TypeError(_('Incorrect arguments to "%(fn_name)s" '
'should be: %(example)s') % self.fmt_data)
@ -1214,7 +1211,7 @@ class Yaql(function.Function):
self._parse(self._expression)
def _parse(self, expression):
if not isinstance(expression, six.string_types):
if not isinstance(expression, str):
raise TypeError(_('The "expression" argument to %s must '
'contain a string.') % self.fn_name)
@ -1282,7 +1279,7 @@ class If(function.Macro):
try:
if (not self.args or
not isinstance(self.args, collections.Sequence) or
isinstance(self.args, six.string_types)):
isinstance(self.args, str)):
raise ValueError()
condition, value_if_true, value_if_false = self.args
except ValueError:
@ -1311,7 +1308,7 @@ class ConditionBoolean(function.Function):
def _check_args(self):
if not (isinstance(self.args, collections.Sequence) and
not isinstance(self.args, six.string_types)):
not isinstance(self.args, str)):
msg = _('Arguments to "%s" must be a list of conditions')
raise ValueError(msg % self.fn_name)
if not self.args or len(self.args) < 2:
@ -1406,7 +1403,7 @@ class Filter(function.Function):
def _parse_args(self):
if (not isinstance(self.args, collections.Sequence) or
isinstance(self.args, six.string_types)):
isinstance(self.args, str)):
raise TypeError(_('Argument to "%s" must be a list') %
self.fn_name)
@ -1476,7 +1473,7 @@ class MakeURL(function.Function):
elif arg == self.PORT:
port = args[arg]
if not isinstance(port, function.Function):
if not isinstance(port, six.integer_types):
if not isinstance(port, int):
try:
port = int(port)
except ValueError:
@ -1493,7 +1490,7 @@ class MakeURL(function.Function):
'must be in range 1-65535') % port)
else:
if not isinstance(args[arg], (function.Function,
six.string_types)):
str)):
raise TypeError(_('The "%(arg)s" argument to '
'"%(fn_name)s" must be a string') %
{'arg': arg,
@ -1544,7 +1541,7 @@ class MakeURL(function.Function):
port = args.get(self.PORT, '')
if port:
yield ':'
yield six.text_type(port)
yield str(port)
path = urlparse.quote(args.get(self.PATH, ''))
@ -1584,7 +1581,7 @@ class ListConcat(function.Function):
def result(self):
args = function.resolve(self.args)
if (isinstance(args, six.string_types) or
if (isinstance(args, str) or
not isinstance(args, collections.Sequence)):
raise TypeError(_('Incorrect arguments to "%(fn_name)s" '
'should be: %(example)s') % self.fmt_data)
@ -1593,7 +1590,7 @@ class ListConcat(function.Function):
if m is None:
return []
elif (isinstance(m, collections.Sequence) and
not isinstance(m, six.string_types)):
not isinstance(m, str)):
return m
else:
msg = _('Incorrect arguments: Items to concat must be lists. '

View File

@ -12,8 +12,6 @@
import functools
import six
from heat.common import exception
from heat.common.i18n import _
from heat.engine.cfn import functions as cfn_funcs
@ -159,7 +157,7 @@ class HOTemplate20130523(template_common.CommonTemplate):
if not attrs:
raise exception.StackValidationFailed(message=message)
try:
for attr, attr_value in six.iteritems(attrs):
for attr, attr_value in attrs.items():
if attr not in allowed_keys:
raise KeyError(err_msg % attr)
if sub_section not in attrs:
@ -183,7 +181,7 @@ class HOTemplate20130523(template_common.CommonTemplate):
for name, attrs in sorted(data.items()):
cfn_object = {}
for attr, attr_value in six.iteritems(attrs):
for attr, attr_value in attrs.items():
cfn_attr = mapping[attr]
if cfn_attr is not None:
cfn_object[cfn_attr] = attr_value
@ -201,18 +199,18 @@ class HOTemplate20130523(template_common.CommonTemplate):
def get_section_name(self, section):
cfn_to_hot_attrs = dict(
zip(six.itervalues(self._HOT_TO_CFN_ATTRS),
six.iterkeys(self._HOT_TO_CFN_ATTRS)))
zip(self._HOT_TO_CFN_ATTRS.values(),
self._HOT_TO_CFN_ATTRS.keys()))
return cfn_to_hot_attrs.get(section, section)
def param_schemata(self, param_defaults=None):
parameter_section = self.t.get(self.PARAMETERS) or {}
pdefaults = param_defaults or {}
for name, schema in six.iteritems(parameter_section):
for name, schema in parameter_section.items():
if name in pdefaults:
parameter_section[name]['default'] = pdefaults[name]
params = six.iteritems(parameter_section)
params = parameter_section.items()
return dict((name, self.param_schema_class.from_dict(name, schema))
for name, schema in params)
@ -228,7 +226,7 @@ class HOTemplate20130523(template_common.CommonTemplate):
valid_keys = frozenset(self._RESOURCE_KEYS)
def defns():
for name, snippet in six.iteritems(resources):
for name, snippet in resources.items():
try:
invalid_keys = set(snippet) - valid_keys
if invalid_keys:
@ -239,7 +237,7 @@ class HOTemplate20130523(template_common.CommonTemplate):
defn_data = dict(self._rsrc_defn_args(stack, name,
snippet))
except (TypeError, ValueError, KeyError) as ex:
msg = six.text_type(ex)
msg = str(ex)
raise exception.StackValidationFailed(message=msg)
defn = rsrc_defn.ResourceDefinition(name, **defn_data)
@ -250,7 +248,7 @@ class HOTemplate20130523(template_common.CommonTemplate):
enabled = conditions.is_enabled(cond_name)
except ValueError as exc:
path = [self.RESOURCES, name, self.RES_CONDITION]
message = six.text_type(exc)
message = str(exc)
raise exception.StackValidationFailed(path=path,
message=message)
if not enabled:
@ -490,7 +488,7 @@ class HOTemplate20161014(HOTemplate20160408):
tmpl, template_id, files, env)
self._parser_condition_functions = {}
for n, f in six.iteritems(self.functions):
for n, f in self.functions.items():
if not f == hot_funcs.Removed:
self._parser_condition_functions[n] = function.Invalid
else:
@ -512,14 +510,14 @@ class HOTemplate20161014(HOTemplate20160408):
yield ('external_id',
self._parse_resource_field(self.RES_EXTERNAL_ID,
(six.string_types,
(str,
function.Function),
'string',
name, data, parse))
yield ('condition',
self._parse_resource_field(self.RES_CONDITION,
(six.string_types, bool,
(str, bool,
function.Function),
'string_or_boolean',
name, data, parse_cond))

View File

@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
class NodeData(object):
"""Data about a node in the graph, to be passed along to other nodes."""
@ -53,8 +51,8 @@ class NodeData(object):
"""Return a dict of all available top-level attribute values."""
attrs = {k: v
for k, v in self._attributes.items()
if isinstance(k, six.string_types)}
for v in six.itervalues(attrs):
if isinstance(k, str)}
for v in attrs.values():
if isinstance(v, Exception):
raise v
return attrs
@ -69,7 +67,7 @@ class NodeData(object):
def attribute_names(self):
"""Iterate over valid top-level attribute names."""
for key in self._attributes:
if isinstance(key, six.string_types):
if isinstance(key, str):
yield key
else:
yield key[0]
@ -80,7 +78,7 @@ class NodeData(object):
This is the format that is serialised and stored in the database's
SyncPoints.
"""
for v in six.itervalues(self._attributes):
for v in self._attributes.values():
if isinstance(v, Exception):
raise v

View File

@ -13,7 +13,6 @@
import collections
import copy
import six
from heat.common import exception
from heat.engine import function
@ -47,8 +46,7 @@ class OutputDefinition(object):
if self._deps is None:
try:
required_resources = function.dependencies(self._value)
self._deps = set(six.moves.map(lambda rp: rp.name,
required_resources))
self._deps = set(map(lambda rp: rp.name, required_resources))
except (exception.InvalidTemplateAttribute,
exception.InvalidTemplateReference):
# This output ain't gonna work anyway
@ -83,7 +81,7 @@ class OutputDefinition(object):
if self._description is None:
return 'No description given'
return six.text_type(self._description)
return str(self._description)
def render_hot(self):
def items():

View File

@ -18,7 +18,6 @@ import itertools
from oslo_serialization import jsonutils
from oslo_utils import encodeutils
from oslo_utils import strutils
import six
from heat.common import exception
from heat.common.i18n import _
@ -87,8 +86,7 @@ class Schema(constr.Schema):
message=_('Default must be a comma-delimited list '
'string: %s') % err)
elif self.type == self.LIST and isinstance(self.default, list):
default_value = [(six.text_type(x))
for x in self.default]
default_value = [(str(x)) for x in self.default]
try:
self.validate_constraints(default_value, context,
[constr.CustomConstraint])
@ -184,7 +182,6 @@ class Schema(constr.Schema):
return super(Schema, self).__getitem__(key)
@six.python_2_unicode_compatible
class Parameter(object):
"""A template parameter."""
@ -247,10 +244,10 @@ class Parameter(object):
else:
raise exception.UserParameterMissing(key=self.name)
except exception.StackValidationFailed as ex:
msg = err_msg % dict(name=self.name, exp=six.text_type(ex))
msg = err_msg % dict(name=self.name, exp=str(ex))
raise exception.StackValidationFailed(message=msg)
except exception.InvalidSchemaError as ex:
msg = err_msg % dict(name=self.name, exp=six.text_type(ex))
msg = err_msg % dict(name=self.name, exp=str(ex))
raise exception.InvalidSchemaError(message=msg)
def value(self):
@ -302,13 +299,13 @@ class Parameter(object):
@classmethod
def _value_as_text(cls, value):
return six.text_type(value)
return str(value)
def __str__(self):
"""Return a string representation of the parameter."""
value = self.value()
if self.hidden():
return six.text_type('******')
return str('******')
else:
return self._value_as_text(value)
@ -330,7 +327,7 @@ class NumberParam(Parameter):
try:
Schema.str_to_num(val)
except (ValueError, TypeError) as ex:
raise exception.StackValidationFailed(message=six.text_type(ex))
raise exception.StackValidationFailed(message=str(ex))
self.schema.validate_value(val, context)
def value(self):
@ -346,7 +343,7 @@ class BooleanParam(Parameter):
try:
strutils.bool_from_string(val, strict=True)
except ValueError as ex:
raise exception.StackValidationFailed(message=six.text_type(ex))
raise exception.StackValidationFailed(message=str(ex))
self.schema.validate_value(val, context)
def value(self):
@ -402,12 +399,12 @@ class CommaDelimitedListParam(ParsedParameter, collections.Sequence):
def parse(self, value):
# only parse when value is not already a list
if isinstance(value, list):
return [(six.text_type(x)) for x in value]
return [(str(x)) for x in value]
try:
return param_utils.delim_string_to_list(value)
except (KeyError, AttributeError) as err:
message = _('Value must be a comma-delimited list string: %s')
raise ValueError(message % six.text_type(err))
raise ValueError(message % str(err))
return value
def value(self):
@ -432,7 +429,7 @@ class CommaDelimitedListParam(ParsedParameter, collections.Sequence):
try:
parsed = self.parse(val)
except ValueError as ex:
raise exception.StackValidationFailed(message=six.text_type(ex))
raise exception.StackValidationFailed(message=str(ex))
self.schema.validate_value(parsed, context)
@ -448,7 +445,7 @@ class JsonParam(ParsedParameter):
def parse(self, value):
try:
val = value
if not isinstance(val, six.string_types):
if not isinstance(val, str):
# turn off oslo_serialization's clever to_primitive()
val = jsonutils.dumps(val, default=None)
if val:
@ -481,12 +478,11 @@ class JsonParam(ParsedParameter):
try:
parsed = self.parse(val)
except ValueError as ex:
raise exception.StackValidationFailed(message=six.text_type(ex))
raise exception.StackValidationFailed(message=str(ex))
self.schema.validate_value(parsed, context)
@six.add_metaclass(abc.ABCMeta)
class Parameters(collections.Mapping):
class Parameters(collections.Mapping, metaclass=abc.ABCMeta):
"""Parameters of a stack.
The parameters of a stack, with type checking, defaults, etc. specified by
@ -513,7 +509,7 @@ class Parameters(collections.Mapping):
schemata = self.tmpl.param_schemata()
user_parameters = (user_parameter(si) for si in
six.iteritems(schemata))
schemata.items())
pseudo_parameters = self._pseudo_parameters(stack_identifier)
self.params = dict((p.name,
@ -534,7 +530,7 @@ class Parameters(collections.Mapping):
"""
self._validate_user_parameters()
for param in six.itervalues(self.params):
for param in self.params.values():
param.validate(validate_value, context)
def __contains__(self, key):
@ -560,7 +556,7 @@ class Parameters(collections.Mapping):
function) and return the resulting dictionary.
"""
return dict((n, func(p))
for n, p in six.iteritems(self.params) if filter_func(p))
for n, p in self.params.items() if filter_func(p))
def set_stack_id(self, stack_identifier):
"""Set the StackId pseudo parameter value."""

View File

@ -17,7 +17,6 @@ import sys
from oslo_config import cfg
from oslo_log import log
import six
from heat.common import plugin_loader
@ -49,15 +48,14 @@ class PluginManager(object):
'heat.engine')
def modules():
pkg_modules = six.moves.map(plugin_loader.load_modules,
packages())
pkg_modules = map(plugin_loader.load_modules, packages())
return itertools.chain.from_iterable(pkg_modules)
self.modules = list(modules())
def map_to_modules(self, function):
"""Iterate over the results of calling a function on every module."""
return six.moves.map(function, self.modules)
return map(function, self.modules)
class PluginMapping(object):
@ -72,7 +70,7 @@ class PluginMapping(object):
mappings provided by that module. Any other arguments passed will be
passed to the mapping functions.
"""
if isinstance(names, six.string_types):
if isinstance(names, str):
names = [names]
self.names = ['%s_mapping' % name for name in names]
@ -109,5 +107,5 @@ class PluginMapping(object):
Mappings are returned as a list of (key, value) tuples.
"""
mod_dicts = plugin_manager.map_to_modules(self.load_from_module)
return itertools.chain.from_iterable(six.iteritems(d) for d
return itertools.chain.from_iterable(d.items() for d
in mod_dicts)

View File

@ -14,7 +14,6 @@
import collections
from oslo_serialization import jsonutils
import six
from heat.common import exception
from heat.common.i18n import _
@ -274,9 +273,9 @@ class Property(object):
def _get_string(self, value):
if value is None:
value = self.has_default() and self.default() or ''
if not isinstance(value, six.string_types):
if not isinstance(value, str):
if isinstance(value, (bool, int)):
value = six.text_type(value)
value = str(value)
else:
raise ValueError(_('Value must be a string; got %r') % value)
return value
@ -306,24 +305,23 @@ class Property(object):
# via a provider resource, in particular lists-of-dicts which
# cannot be handled correctly via comma_delimited_list
if self.schema.allow_conversion:
if isinstance(value, six.string_types):
if isinstance(value, str):
return value
elif isinstance(value, collections.Sequence):
return jsonutils.dumps(value)
raise TypeError(_('"%s" is not a map') % value)
return dict(self._get_children(six.iteritems(value),
return dict(self._get_children(value.items(),
validate=validate,
translation=translation))
def _get_list(self, value, validate=False, translation=None):
if value is None:
value = self.has_default() and self.default() or []
if self.schema.allow_conversion and isinstance(value,
six.string_types):
if self.schema.allow_conversion and isinstance(value, str):
value = param_utils.delim_string_to_list(value)
if (not isinstance(value, collections.Sequence) or
isinstance(value, six.string_types)):
isinstance(value, str)):
raise TypeError(_('"%s" is not a list') % repr(value))
return [v[1] for v in self._get_children(enumerate(value),
@ -341,7 +339,7 @@ class Property(object):
value = self.has_default() and self.default() or False
if isinstance(value, bool):
return value
if isinstance(value, six.string_types):
if isinstance(value, str):
normalised = value.lower()
if normalised not in ['true', 'false']:
raise ValueError(_('"%s" is not a valid boolean') % normalised)
@ -432,7 +430,7 @@ class Properties(collections.Mapping):
else:
path = [key]
raise exception.StackValidationFailed(
path=path, message=six.text_type(e))
path=path, message=str(e))
# are there unimplemented Properties
if not prop.implemented() and key in self.data:
@ -488,7 +486,7 @@ class Properties(collections.Mapping):
# the resolver function could raise any number of exceptions,
# so handle this generically
except Exception as e:
raise ValueError(six.text_type(e))
raise ValueError(str(e))
def _get_property_value(self, key, validate=False):
if key not in self:
@ -658,7 +656,7 @@ class Properties(collections.Mapping):
return {}, {}
param_prop_defs = [param_prop_def_items(n, s, template_type)
for n, s in six.iteritems(schemata(schema))
for n, s in schemata(schema).items()
if s.implemented]
param_items, prop_items = zip(*param_prop_defs)
return dict(param_items), dict(prop_items)