diff options
Diffstat (limited to 'heat')
27 files changed, 119 insertions, 112 deletions
diff --git a/heat/common/environment_util.py b/heat/common/environment_util.py index abf081bd0..8a6ed4393 100644 --- a/heat/common/environment_util.py +++ b/heat/common/environment_util.py @@ -57,10 +57,10 @@ def merge_map(old, new, deep_merge=False): if v is not None: if not deep_merge: old[k] = v - elif isinstance(v, collections.Mapping): + elif isinstance(v, collections.abc.Mapping): old_v = old.get(k) old[k] = merge_map(old_v, v, deep_merge) if old_v else v - elif (isinstance(v, collections.Sequence) and + elif (isinstance(v, collections.abc.Sequence) and not isinstance(v, str)): old_v = old.get(k) old[k] = merge_list(old_v, v) if old_v else v @@ -79,7 +79,7 @@ def parse_param(p_val, p_schema): p_val = jsonutils.dumps(p_val) if p_val: return jsonutils.loads(p_val) - elif not isinstance(p_val, collections.Sequence): + elif not isinstance(p_val, collections.abc.Sequence): raise ValueError() except (ValueError, TypeError) as err: msg = _("Invalid parameter in environment %s.") % str(err) diff --git a/heat/common/identifier.py b/heat/common/identifier.py index 46323b25d..02628b478 100644 --- a/heat/common/identifier.py +++ b/heat/common/identifier.py @@ -20,7 +20,7 @@ from urllib import parse as urlparse from heat.common.i18n import _ -class HeatIdentifier(collections.Mapping): +class HeatIdentifier(collections.abc.Mapping): FIELDS = ( TENANT, STACK_NAME, STACK_ID, PATH diff --git a/heat/engine/api.py b/heat/engine/api.py index ceb881470..35edaff6e 100644 --- a/heat/engine/api.py +++ b/heat/engine/api.py @@ -292,7 +292,7 @@ def format_resource_attributes(resource, with_attr=None): if 'show' in resolver: show_attr = resolve('show', resolver) # check if 'show' resolved to dictionary. so it's not None - if isinstance(show_attr, collections.Mapping): + if isinstance(show_attr, collections.abc.Mapping): for a in with_attr: if a not in show_attr: show_attr[a] = resolve(a, resolver) diff --git a/heat/engine/attributes.py b/heat/engine/attributes.py index 26c7a9676..eb2c5667f 100644 --- a/heat/engine/attributes.py +++ b/heat/engine/attributes.py @@ -138,7 +138,7 @@ BASE_ATTRIBUTES = (SHOW_ATTR, ) = ('show', ) ALL_ATTRIBUTES = '*' -class Attributes(collections.Mapping): +class Attributes(collections.abc.Mapping): """Models a collection of Resource Attributes.""" def __init__(self, res_name, schema, resolver): @@ -212,14 +212,14 @@ class Attributes(collections.Mapping): {'name': attrib.name, 'att_type': attrib.schema.STRING}) elif attrib.schema.type == attrib.schema.LIST: - if (not isinstance(value, collections.Sequence) + if (not isinstance(value, collections.abc.Sequence) or isinstance(value, str)): LOG.warning("Attribute %(name)s is not of type " "%(att_type)s", {'name': attrib.name, 'att_type': attrib.schema.LIST}) elif attrib.schema.type == attrib.schema.MAP: - if not isinstance(value, collections.Mapping): + if not isinstance(value, collections.abc.Mapping): LOG.warning("Attribute %(name)s is not of type " "%(att_type)s", {'name': attrib.name, @@ -307,8 +307,8 @@ def select_from_attribute(attribute_value, path): :returns: the selected attribute component value. """ def get_path_component(collection, key): - if not isinstance(collection, (collections.Mapping, - collections.Sequence)): + if not isinstance(collection, (collections.abc.Mapping, + collections.abc.Sequence)): raise TypeError(_("Can't traverse attribute path")) if not isinstance(key, (str, int)): diff --git a/heat/engine/cfn/functions.py b/heat/engine/cfn/functions.py index ccd9c4d47..f037eec0c 100644 --- a/heat/engine/cfn/functions.py +++ b/heat/engine/cfn/functions.py @@ -168,7 +168,7 @@ class Select(function.Function): 'err': json_ex} raise ValueError(_('"%(fn_name)s": %(err)s') % fmt_data) - if isinstance(strings, collections.Mapping): + if isinstance(strings, collections.abc.Mapping): if not isinstance(index, str): raise TypeError(_('Index to "%s" must be a string') % self.fn_name) @@ -179,7 +179,7 @@ class Select(function.Function): except (ValueError, TypeError): pass - if (isinstance(strings, collections.Sequence) and + if (isinstance(strings, collections.abc.Sequence) and not isinstance(strings, str)): if not isinstance(index, int): raise TypeError(_('Index to "%s" must be an integer') % @@ -229,7 +229,7 @@ class Split(function.Function): fmt_data = {'fn_name': self.fn_name, 'example': example} - if isinstance(self.args, (str, collections.Mapping)): + if isinstance(self.args, (str, collections.abc.Mapping)): raise TypeError(_('Incorrect arguments to "%(fn_name)s" ' 'should be: %(example)s') % fmt_data) @@ -278,7 +278,7 @@ class Replace(hot_funcs.Replace): fmt_data = {'fn_name': self.fn_name, 'example': example} - if isinstance(self.args, (str, collections.Mapping)): + if isinstance(self.args, (str, collections.abc.Mapping)): raise TypeError(_('Incorrect arguments to "%(fn_name)s" ' 'should be: %(example)s') % fmt_data) @@ -350,7 +350,7 @@ class MemberListToMap(function.Function): def result(self): member_list = function.resolve(self._list) - if not isinstance(member_list, collections.Iterable): + if not isinstance(member_list, collections.abc.Iterable): raise TypeError(_('Member list must be a list')) def item(s): @@ -428,7 +428,7 @@ class Not(hot_funcs.Not): msg = _('Arguments to "%s" must be of the form: ' '[condition]') % self.fn_name if (not self.args or - not isinstance(self.args, collections.Sequence) or + not isinstance(self.args, collections.abc.Sequence) or isinstance(self.args, str)): raise ValueError(msg) if len(self.args) != 1: diff --git a/heat/engine/clients/os/nova.py b/heat/engine/clients/os/nova.py index c634388ad..bb3a8adde 100644 --- a/heat/engine/clients/os/nova.py +++ b/heat/engine/clients/os/nova.py @@ -596,7 +596,7 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers def meta_serialize(self, metadata): """Serialize non-string metadata values before sending them to Nova.""" - if not isinstance(metadata, collections.Mapping): + if not isinstance(metadata, collections.abc.Mapping): raise exception.StackValidationFailed(message=_( "nova server metadata needs to be a Map.")) @@ -647,7 +647,7 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers """ nc = self.client - class ConsoleUrls(collections.Mapping): + class ConsoleUrls(collections.abc.Mapping): def __init__(self, server): self.console_method = server.get_console_url self.support_console_types = ['novnc', 'xvpvnc', diff --git a/heat/engine/conditions.py b/heat/engine/conditions.py index 1e3d7e6a4..73e51f485 100644 --- a/heat/engine/conditions.py +++ b/heat/engine/conditions.py @@ -24,7 +24,7 @@ _in_progress = object() class Conditions(object): def __init__(self, conditions_dict): - assert isinstance(conditions_dict, collections.Mapping) + assert isinstance(conditions_dict, collections.abc.Mapping) self._conditions = conditions_dict self._resolved = {} diff --git a/heat/engine/constraints.py b/heat/engine/constraints.py index f6ca11e3e..dfed2c969 100644 --- a/heat/engine/constraints.py +++ b/heat/engine/constraints.py @@ -36,7 +36,7 @@ MEMOIZE = core.get_memoization_decorator(conf=cfg.CONF, LOG = log.getLogger(__name__) -class Schema(collections.Mapping): +class Schema(collections.abc.Mapping): """Schema base class for validating properties or parameters. Schema objects are serializable to dictionaries following a superset of @@ -251,7 +251,7 @@ class Schema(collections.Mapping): return self._len -class AnyIndexDict(collections.Mapping): +class AnyIndexDict(collections.abc.Mapping): """A Mapping that returns the same value for any integer index. Used for storing the schema for a list. When converted to a dictionary, @@ -276,7 +276,7 @@ class AnyIndexDict(collections.Mapping): return 1 -class Constraint(collections.Mapping): +class Constraint(collections.abc.Mapping): """Parent class for constraints on allowable values for a Property. Constraints are serializable to dictionaries following the HOT input @@ -540,7 +540,7 @@ class AllowedValues(Constraint): def __init__(self, allowed, description=None): super(AllowedValues, self).__init__(description) - if (not isinstance(allowed, collections.Sequence) or + if (not isinstance(allowed, collections.abc.Sequence) or isinstance(allowed, str)): raise exception.InvalidSchemaError( message=_('AllowedValues must be a list')) diff --git a/heat/engine/environment.py b/heat/engine/environment.py index 8defdf31f..f425e3c2c 100644 --- a/heat/engine/environment.py +++ b/heat/engine/environment.py @@ -55,7 +55,7 @@ def is_hook_definition(key, value): if key == 'hooks': if isinstance(value, str): is_valid_hook = valid_hook_type(value) - elif isinstance(value, collections.Sequence): + elif isinstance(value, collections.abc.Sequence): is_valid_hook = all(valid_hook_type(hook) for hook in value) if not is_valid_hook: @@ -72,7 +72,7 @@ def is_valid_restricted_action(key, value): if key == 'restricted_actions': if isinstance(value, str): valid_action = valid_restricted_actions(value) - elif isinstance(value, collections.Sequence): + elif isinstance(value, collections.abc.Sequence): valid_action = all(valid_restricted_actions( action) for action in value) @@ -397,7 +397,7 @@ class ResourceRegistry(object): actions = resource['restricted_actions'] if isinstance(actions, str): restricted_actions.add(actions) - elif isinstance(actions, collections.Sequence): + elif isinstance(actions, collections.abc.Sequence): restricted_actions |= set(actions) return restricted_actions @@ -433,7 +433,7 @@ class ResourceRegistry(object): if isinstance(hooks, str): if hook == hooks: return True - elif isinstance(hooks, collections.Sequence): + elif isinstance(hooks, collections.abc.Sequence): if hook in hooks: return True return False diff --git a/heat/engine/function.py b/heat/engine/function.py index f2e68e1cb..2169e2194 100644 --- a/heat/engine/function.py +++ b/heat/engine/function.py @@ -266,12 +266,12 @@ def resolve(snippet, nullable=False): result = None return result - if isinstance(snippet, collections.Mapping): + if isinstance(snippet, collections.abc.Mapping): return dict(filter(_non_null_item, ((k, resolve(v, nullable=True)) for k, v in snippet.items()))) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): return list(filter(_non_null_value, (resolve(v, nullable=True) for v in snippet))) @@ -293,11 +293,11 @@ def validate(snippet, path=None): raise exception.StackValidationFailed( path=path + [snippet.fn_name], message=str(e)) - elif isinstance(snippet, collections.Mapping): + elif isinstance(snippet, collections.abc.Mapping): for k, v in snippet.items(): validate(v, path + [k]) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): basepath = list(path) parent = basepath.pop() if basepath else '' for i, v in enumerate(snippet): @@ -314,7 +314,7 @@ def dependencies(snippet, path=''): if isinstance(snippet, Function): return snippet.dependencies(path) - elif isinstance(snippet, collections.Mapping): + elif isinstance(snippet, collections.abc.Mapping): def mkpath(key): return '.'.join([path, str(key)]) @@ -323,7 +323,7 @@ def dependencies(snippet, path=''): return itertools.chain.from_iterable(deps) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): def mkpath(idx): return ''.join([path, '[%d]' % idx]) @@ -348,11 +348,11 @@ def dep_attrs(snippet, resource_name): if isinstance(snippet, Function): return snippet.dep_attrs(resource_name) - elif isinstance(snippet, collections.Mapping): + elif isinstance(snippet, collections.abc.Mapping): attrs = (dep_attrs(val, resource_name) for val in snippet.values()) return itertools.chain.from_iterable(attrs) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): attrs = (dep_attrs(value, resource_name) for value in snippet) return itertools.chain.from_iterable(attrs) return [] @@ -371,11 +371,11 @@ def all_dep_attrs(snippet): if isinstance(snippet, Function): return snippet.all_dep_attrs() - elif isinstance(snippet, collections.Mapping): + elif isinstance(snippet, collections.abc.Mapping): res_attrs = (all_dep_attrs(value) for value in snippet.values()) return itertools.chain.from_iterable(res_attrs) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): res_attrs = (all_dep_attrs(value) for value in snippet) return itertools.chain.from_iterable(res_attrs) return [] diff --git a/heat/engine/hot/functions.py b/heat/engine/hot/functions.py index a700ff5fe..33b75f4e4 100644 --- a/heat/engine/hot/functions.py +++ b/heat/engine/hot/functions.py @@ -79,7 +79,7 @@ class GetParam(function.Function): if isinstance(args, str): param_name = args path_components = [] - elif isinstance(args, collections.Sequence): + elif isinstance(args, collections.abc.Sequence): param_name = args[0] path_components = args[1:] else: @@ -96,15 +96,15 @@ class GetParam(function.Function): raise exception.UserParameterMissing(key=param_name) def get_path_component(collection, key): - if not isinstance(collection, (collections.Mapping, - collections.Sequence)): + if not isinstance(collection, (collections.abc.Mapping, + collections.abc.Sequence)): raise TypeError(_('"%s" can\'t traverse path') % self.fn_name) if not isinstance(key, (str, int)): raise TypeError(_('Path components in "%s" ' 'must be strings') % self.fn_name) - if isinstance(collection, collections.Sequence + if isinstance(collection, collections.abc.Sequence ) and isinstance(key, str): try: key = int(key) @@ -167,7 +167,7 @@ class GetAttThenSelect(function.Function): self._path_components) = self._parse_args() def _parse_args(self): - if (not isinstance(self.args, collections.Sequence) or + if (not isinstance(self.args, collections.abc.Sequence) or isinstance(self.args, str)): raise TypeError(_('Argument to "%s" must be a list') % self.fn_name) @@ -314,7 +314,7 @@ class GetAttAllAttributes(GetAtt): 'forms: [resource_name] or ' '[resource_name, attribute, (path), ...]' ) % self.fn_name) - elif isinstance(self.args, collections.Sequence): + elif isinstance(self.args, collections.abc.Sequence): if len(self.args) > 1: return super(GetAttAllAttributes, self)._parse_args() else: @@ -372,12 +372,12 @@ class Replace(function.Function): self._mapping, self._string = self._parse_args() if not isinstance(self._mapping, - (collections.Mapping, function.Function)): + (collections.abc.Mapping, function.Function)): raise TypeError(_('"%s" parameters must be a mapping') % self.fn_name) def _parse_args(self): - if not isinstance(self.args, collections.Mapping): + if not isinstance(self.args, collections.abc.Mapping): raise TypeError(_('Arguments to "%s" must be a map') % self.fn_name) @@ -418,7 +418,7 @@ class Replace(function.Function): if not isinstance(template, str): raise TypeError(_('"%s" template must be a string') % self.fn_name) - if not isinstance(mapping, collections.Mapping): + if not isinstance(mapping, collections.abc.Mapping): raise TypeError(_('"%s" params must be a map') % self.fn_name) def replace(strings, keys): @@ -490,9 +490,10 @@ class ReplaceJson(Replace): else: _raise_empty_param_value_error() - if not isinstance(value, (str, int, - float, bool)): - if isinstance(value, (collections.Mapping, collections.Sequence)): + if not isinstance(value, (str, int, float, bool)): + if isinstance( + value, (collections.abc.Mapping, collections.abc.Sequence) + ): if not self._allow_empty_value and len(value) == 0: _raise_empty_param_value_error() try: @@ -604,7 +605,7 @@ class Join(function.Function): if strings is None: strings = [] if (isinstance(strings, str) or - not isinstance(strings, collections.Sequence)): + not isinstance(strings, collections.abc.Sequence)): raise TypeError(_('"%s" must operate on a list') % self.fn_name) delim = function.resolve(self._delim) @@ -669,7 +670,7 @@ class JoinMultiple(function.Function): for jl in r_joinlists: if jl: if (isinstance(jl, str) or - not isinstance(jl, collections.Sequence)): + not isinstance(jl, collections.abc.Sequence)): raise TypeError(_('"%s" must operate on ' 'a list') % self.fn_name) @@ -687,7 +688,9 @@ class JoinMultiple(function.Function): return '' elif isinstance(s, str): return s - elif isinstance(s, (collections.Mapping, collections.Sequence)): + elif isinstance( + s, (collections.abc.Mapping, collections.abc.Sequence) + ): try: return jsonutils.dumps(s, default=None, sort_keys=True) except TypeError: @@ -725,14 +728,14 @@ class MapMerge(function.Function): def result(self): args = function.resolve(self.args) - if not isinstance(args, collections.Sequence): + if not isinstance(args, collections.abc.Sequence): raise TypeError(_('Incorrect arguments to "%(fn_name)s" ' 'should be: %(example)s') % self.fmt_data) def ensure_map(m): if m is None: return {} - elif isinstance(m, collections.Mapping): + elif isinstance(m, collections.abc.Mapping): return m else: msg = _('Incorrect arguments: Items to merge must be maps.') @@ -776,7 +779,7 @@ class MapReplace(function.Function): def ensure_map(m): if m is None: return {} - elif isinstance(m, collections.Mapping): + elif isinstance(m, collections.abc.Mapping): return m else: msg = (_('Incorrect arguments: to "%(fn_name)s", arguments ' @@ -901,7 +904,7 @@ class Repeat(function.Function): self._parse_args() def _parse_args(self): - if not isinstance(self.args, collections.Mapping): + if not isinstance(self.args, collections.abc.Mapping): raise TypeError(_('Arguments to "%s" must be a map') % self.fn_name) @@ -923,12 +926,12 @@ class Repeat(function.Function): super(Repeat, self).validate() if not isinstance(self._for_each, function.Function): - if not isinstance(self._for_each, collections.Mapping): + if not isinstance(self._for_each, collections.abc.Mapping): raise TypeError(_('The "for_each" argument to "%s" must ' 'contain a map') % self.fn_name) def _valid_arg(self, arg): - if not (isinstance(arg, (collections.Sequence, + if not (isinstance(arg, (collections.abc.Sequence, function.Function)) and not isinstance(arg, str)): raise TypeError(_('The values of the "for_each" argument to ' @@ -939,10 +942,10 @@ class Repeat(function.Function): for (key, value) in zip(keys, values): template = template.replace(key, value) return template - elif isinstance(template, collections.Sequence): + elif isinstance(template, collections.abc.Sequence): return [self._do_replacement(keys, values, elem) for elem in template] - elif isinstance(template, collections.Mapping): + elif isinstance(template, collections.abc.Mapping): return dict((self._do_replacement(keys, values, k), self._do_replacement(keys, values, v)) for (k, v) in template.items()) @@ -993,8 +996,8 @@ class RepeatWithMap(Repeat): """ def _valid_arg(self, arg): - if not (isinstance(arg, (collections.Sequence, - collections.Mapping, + if not (isinstance(arg, (collections.abc.Sequence, + collections.abc.Mapping, function.Function)) and not isinstance(arg, str)): raise TypeError(_('The values of the "for_each" argument to ' @@ -1118,7 +1121,7 @@ class StrSplit(function.Function): 'example': example} self.fn_name = fn_name - if isinstance(args, (str, collections.Mapping)): + if isinstance(args, (str, collections.abc.Mapping)): raise TypeError(_('Incorrect arguments to "%(fn_name)s" ' 'should be: %(example)s') % self.fmt_data) @@ -1188,7 +1191,7 @@ class Yaql(function.Function): def __init__(self, stack, fn_name, args): super(Yaql, self).__init__(stack, fn_name, args) - if not isinstance(self.args, collections.Mapping): + if not isinstance(self.args, collections.abc.Mapping): raise TypeError(_('Arguments to "%s" must be a map.') % self.fn_name) @@ -1281,7 +1284,7 @@ class If(function.Macro): def parse_args(self, parse_func): try: if (not self.args or - not isinstance(self.args, collections.Sequence) or + not isinstance(self.args, collections.abc.Sequence) or isinstance(self.args, str)): raise ValueError() condition, value_if_true, value_if_false = self._read_args() @@ -1344,7 +1347,7 @@ class ConditionBoolean(function.Function): self._check_args() def _check_args(self): - if not (isinstance(self.args, collections.Sequence) and + if not (isinstance(self.args, collections.abc.Sequence) and not isinstance(self.args, str)): msg = _('Arguments to "%s" must be a list of conditions') raise ValueError(msg % self.fn_name) @@ -1439,7 +1442,7 @@ class Filter(function.Function): self._values, self._sequence = self._parse_args() def _parse_args(self): - if (not isinstance(self.args, collections.Sequence) or + if (not isinstance(self.args, collections.abc.Sequence) or isinstance(self.args, str)): raise TypeError(_('Argument to "%s" must be a list') % self.fn_name) @@ -1501,7 +1504,7 @@ class MakeURL(function.Function): if arg in args: if arg == self.QUERY: if not isinstance(args[arg], (function.Function, - collections.Mapping)): + collections.abc.Mapping)): raise TypeError(_('The "%(arg)s" argument to ' '"%(fn_name)s" must be a map') % {'arg': arg, @@ -1536,7 +1539,7 @@ class MakeURL(function.Function): def validate(self): super(MakeURL, self).validate() - if not isinstance(self.args, collections.Mapping): + if not isinstance(self.args, collections.abc.Mapping): raise TypeError(_('The arguments to "%s" must ' 'be a map') % self.fn_name) @@ -1619,14 +1622,14 @@ class ListConcat(function.Function): args = function.resolve(self.args) if (isinstance(args, str) or - not isinstance(args, collections.Sequence)): + not isinstance(args, collections.abc.Sequence)): raise TypeError(_('Incorrect arguments to "%(fn_name)s" ' 'should be: %(example)s') % self.fmt_data) def ensure_list(m): if m is None: return [] - elif (isinstance(m, collections.Sequence) and + elif (isinstance(m, collections.abc.Sequence) and not isinstance(m, str)): return m else: @@ -1691,7 +1694,7 @@ class Contains(function.Function): resolved_value = function.resolve(self.value) resolved_sequence = function.resolve(self.sequence) - if not isinstance(resolved_sequence, collections.Sequence): + if not isinstance(resolved_sequence, collections.abc.Sequence): raise TypeError(_('Second argument to "%s" should be ' 'a sequence.') % self.fn_name) diff --git a/heat/engine/parameters.py b/heat/engine/parameters.py index 4aced043b..cb05c6ed7 100644 --- a/heat/engine/parameters.py +++ b/heat/engine/parameters.py @@ -388,7 +388,7 @@ class ParsedParameter(Parameter): return self._parsed -class CommaDelimitedListParam(ParsedParameter, collections.Sequence): +class CommaDelimitedListParam(ParsedParameter, collections.abc.Sequence): """A template parameter of type "CommaDelimitedList".""" __slots__ = tuple() @@ -481,7 +481,7 @@ class JsonParam(ParsedParameter): self.schema.validate_value(parsed, context) -class Parameters(collections.Mapping, metaclass=abc.ABCMeta): +class Parameters(collections.abc.Mapping, metaclass=abc.ABCMeta): """Parameters of a stack. The parameters of a stack, with type checking, defaults, etc. specified by diff --git a/heat/engine/plugin_manager.py b/heat/engine/plugin_manager.py index e929c141c..cde1591aa 100644 --- a/heat/engine/plugin_manager.py +++ b/heat/engine/plugin_manager.py @@ -93,7 +93,7 @@ class PluginMapping(object): 'from %(module)s', fmt_data) raise else: - if isinstance(mapping_dict, collections.Mapping): + if isinstance(mapping_dict, collections.abc.Mapping): return mapping_dict elif mapping_dict is not None: LOG.error('Invalid type for %(mapping_name)s ' diff --git a/heat/engine/properties.py b/heat/engine/properties.py index a3f955d86..2d9623baa 100644 --- a/heat/engine/properties.py +++ b/heat/engine/properties.py @@ -300,14 +300,14 @@ class Property(object): def _get_map(self, value, validate=False, translation=None): if value is None: value = self.default() if self.has_default() else {} - if not isinstance(value, collections.Mapping): + if not isinstance(value, collections.abc.Mapping): # This is to handle passing Lists via Json parameters exposed # 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, str): return value - elif isinstance(value, collections.Sequence): + elif isinstance(value, collections.abc.Sequence): return jsonutils.dumps(value) raise TypeError(_('"%s" is not a map') % value) @@ -320,7 +320,7 @@ class Property(object): value = self.has_default() and self.default() or [] if self.schema.allow_conversion and isinstance(value, str): value = param_utils.delim_string_to_list(value) - if (not isinstance(value, collections.Sequence) or + if (not isinstance(value, collections.abc.Sequence) or isinstance(value, str)): raise TypeError(_('"%s" is not a list') % repr(value)) @@ -376,7 +376,7 @@ def _default_resolver(d, nullable=False): return d -class Properties(collections.Mapping): +class Properties(collections.abc.Mapping): def __init__(self, schema, data, resolver=_default_resolver, parent_name=None, diff --git a/heat/engine/resource.py b/heat/engine/resource.py index e2f51e5c5..de9a708a8 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -1066,7 +1066,7 @@ class Resource(status.ResourceStatus): refd_attrs |= get_dep_attrs(stk_defn.resource_definition(r_name) for r_name in enabled_resources) - subset_outputs = isinstance(in_outputs, collections.Iterable) + subset_outputs = isinstance(in_outputs, collections.abc.Iterable) if subset_outputs or in_outputs: if not subset_outputs: in_outputs = stk_defn.enabled_output_names() diff --git a/heat/engine/resources/openstack/heat/resource_group.py b/heat/engine/resources/openstack/heat/resource_group.py index 85545bf84..48ef05ae9 100644 --- a/heat/engine/resources/openstack/heat/resource_group.py +++ b/heat/engine/resources/openstack/heat/resource_group.py @@ -610,12 +610,12 @@ class ResourceGroup(stack_resource.StackResource): result = None return result - if isinstance(snippet, collections.Mapping): + if isinstance(snippet, collections.abc.Mapping): return dict(filter(function._non_null_item, ((k, ignore_param_resolve(v, nullable=True)) for k, v in snippet.items()))) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): return list(filter(function._non_null_value, (ignore_param_resolve(v, nullable=True) for v in snippet))) @@ -646,9 +646,9 @@ class ResourceGroup(stack_resource.StackResource): if isinstance(val, str): return val.replace(repl_var, res_name) - elif isinstance(val, collections.Mapping): + elif isinstance(val, collections.abc.Mapping): return {k: recurse(v) for k, v in val.items()} - elif isinstance(val, collections.Sequence): + elif isinstance(val, collections.abc.Sequence): return [recurse(v) for v in val] return val diff --git a/heat/engine/resources/openstack/heat/structured_config.py b/heat/engine/resources/openstack/heat/structured_config.py index a23bfceda..abcb676d6 100644 --- a/heat/engine/resources/openstack/heat/structured_config.py +++ b/heat/engine/resources/openstack/heat/structured_config.py @@ -166,7 +166,7 @@ class StructuredDeployment(sd.SoftwareDeployment): input_key, check_input_val=check_input_val) - if isinstance(snippet, collections.Mapping): + if isinstance(snippet, collections.abc.Mapping): fn_arg = StructuredDeployment.get_input_key_arg(snippet, input_key) if fn_arg is not None: return StructuredDeployment.get_input_key_value(fn_arg, inputs, @@ -175,7 +175,7 @@ class StructuredDeployment(sd.SoftwareDeployment): return dict((k, parse(v)) for k, v in snippet.items()) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): return [parse(v) for v in snippet] else: return snippet diff --git a/heat/engine/resources/openstack/neutron/l2_gateway.py b/heat/engine/resources/openstack/neutron/l2_gateway.py index 08f877256..634ee81fc 100644 --- a/heat/engine/resources/openstack/neutron/l2_gateway.py +++ b/heat/engine/resources/openstack/neutron/l2_gateway.py @@ -106,10 +106,10 @@ class L2Gateway(neutron.NeutronResource): @staticmethod def _remove_none_value_props(props): - if isinstance(props, collections.Mapping): + if isinstance(props, collections.abc.Mapping): return dict((k, L2Gateway._remove_none_value_props(v)) for k, v in props.items() if v is not None) - elif (isinstance(props, collections.Sequence) and + elif (isinstance(props, collections.abc.Sequence) and not isinstance(props, str)): return list(L2Gateway._remove_none_value_props(p) for p in props if p is not None) diff --git a/heat/engine/resources/wait_condition.py b/heat/engine/resources/wait_condition.py index 65caeab91..74de91819 100644 --- a/heat/engine/resources/wait_condition.py +++ b/heat/engine/resources/wait_condition.py @@ -57,7 +57,7 @@ class BaseWaitConditionHandle(signal_responder.SignalResponder): return status in self.WAIT_STATUSES def _metadata_format_ok(self, metadata): - if not isinstance(metadata, collections.Mapping): + if not isinstance(metadata, collections.abc.Mapping): return False if set(metadata) != set(self.METADATA_KEYS): return False diff --git a/heat/engine/rsrc_defn.py b/heat/engine/rsrc_defn.py index 24422376a..04e12eed3 100644 --- a/heat/engine/rsrc_defn.py +++ b/heat/engine/rsrc_defn.py @@ -113,17 +113,17 @@ class ResourceDefinition(object): assert isinstance(self.description, str) if properties is not None: - assert isinstance(properties, (collections.Mapping, + assert isinstance(properties, (collections.abc.Mapping, function.Function)) self._hash ^= _hash_data(properties) if metadata is not None: - assert isinstance(metadata, (collections.Mapping, + assert isinstance(metadata, (collections.abc.Mapping, function.Function)) self._hash ^= _hash_data(metadata) if depends is not None: - assert isinstance(depends, (collections.Sequence, + assert isinstance(depends, (collections.abc.Sequence, function.Function)) assert not isinstance(depends, str) self._hash ^= _hash_data(depends) @@ -133,7 +133,7 @@ class ResourceDefinition(object): self._hash ^= _hash_data(deletion_policy) if update_policy is not None: - assert isinstance(update_policy, (collections.Mapping, + assert isinstance(update_policy, (collections.abc.Mapping, function.Function)) self._hash ^= _hash_data(update_policy) @@ -432,10 +432,10 @@ def _hash_data(data): data = copy.deepcopy(data) if not isinstance(data, str): - if isinstance(data, collections.Sequence): + if isinstance(data, collections.abc.Sequence): return hash(tuple(_hash_data(d) for d in data)) - if isinstance(data, collections.Mapping): + if isinstance(data, collections.abc.Mapping): item_hashes = (hash(k) ^ _hash_data(v) for k, v in data.items()) return functools.reduce(operator.xor, item_hashes, 0) diff --git a/heat/engine/software_config_io.py b/heat/engine/software_config_io.py index 6f788554d..3e2906302 100644 --- a/heat/engine/software_config_io.py +++ b/heat/engine/software_config_io.py @@ -178,10 +178,14 @@ def check_io_schema_list(io_configs): Raises TypeError if the list itself is not a list, or if any of the members are not dicts. """ - if (not isinstance(io_configs, collections.Sequence) or - isinstance(io_configs, collections.Mapping) or - isinstance(io_configs, str)): + if ( + not isinstance(io_configs, collections.abc.Sequence) or + isinstance(io_configs, collections.abc.Mapping) or + isinstance(io_configs, str) + ): raise TypeError('Software Config I/O Schema must be in a list') - if not all(isinstance(conf, collections.Mapping) for conf in io_configs): + if not all( + isinstance(conf, collections.abc.Mapping) for conf in io_configs + ): raise TypeError('Software Config I/O Schema must be a dict') diff --git a/heat/engine/stack.py b/heat/engine/stack.py index be3323b8b..02291d087 100644 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -100,7 +100,7 @@ def reset_state_on_error(func): return handle_exceptions -class Stack(collections.Mapping): +class Stack(collections.abc.Mapping): ACTIONS = ( CREATE, DELETE, UPDATE, ROLLBACK, SUSPEND, RESUME, ADOPT, diff --git a/heat/engine/template.py b/heat/engine/template.py index 1e52c8c92..eece1d004 100644 --- a/heat/engine/template.py +++ b/heat/engine/template.py @@ -89,7 +89,7 @@ def get_template_class(template_data): raise exception.InvalidTemplateVersion(explanation=explanation) -class Template(collections.Mapping): +class Template(collections.abc.Mapping): """Abstract base class for template format plugins. All template formats (both internal and third-party) should derive from @@ -355,7 +355,7 @@ class Template(collections.Mapping): def parse(functions, stack, snippet, path='', template=None): recurse = functools.partial(parse, functions, stack, template=template) - if isinstance(snippet, collections.Mapping): + if isinstance(snippet, collections.abc.Mapping): def mkpath(key): return '.'.join([path, str(key)]) @@ -380,7 +380,7 @@ def parse(functions, stack, snippet, path='', template=None): return dict((k, recurse(v, mkpath(k))) for k, v in snippet.items()) elif (not isinstance(snippet, str) and - isinstance(snippet, collections.Iterable)): + isinstance(snippet, collections.abc.Iterable)): def mkpath(idx): return ''.join([path, '[%d]' % idx]) diff --git a/heat/engine/template_common.py b/heat/engine/template_common.py index f13898dc6..f5d80a509 100644 --- a/heat/engine/template_common.py +++ b/heat/engine/template_common.py @@ -80,18 +80,18 @@ class CommonTemplate(template.Template): yield ('properties', self._parse_resource_field(self.RES_PROPERTIES, - (collections.Mapping, + (collections.abc.Mapping, function.Function), 'object', name, data, parse)) yield ('metadata', self._parse_resource_field(self.RES_METADATA, - (collections.Mapping, + (collections.abc.Mapping, function.Function), 'object', name, data, parse)) depends = self._parse_resource_field(self.RES_DEPENDS_ON, - collections.Sequence, + collections.abc.Sequence, 'list or string', name, data, no_parse) if isinstance(depends, str): @@ -122,7 +122,7 @@ class CommonTemplate(template.Template): yield ('update_policy', self._parse_resource_field(self.RES_UPDATE_POLICY, - (collections.Mapping, + (collections.abc.Mapping, function.Function), 'object', name, data, parse)) @@ -143,7 +143,7 @@ class CommonTemplate(template.Template): return cached_conds raw_defs = self._get_condition_definitions() - if not isinstance(raw_defs, collections.Mapping): + if not isinstance(raw_defs, collections.abc.Mapping): message = _('Condition definitions must be a map. Found a ' '%s instead') % type(raw_defs).__name__ raise exception.StackValidationFailed( @@ -166,7 +166,7 @@ class CommonTemplate(template.Template): def get_outputs(): for key, val in outputs.items(): - if not isinstance(val, collections.Mapping): + if not isinstance(val, collections.abc.Mapping): message = _('Output definitions must be a map. Found a ' '%s instead') % type(val).__name__ raise exception.StackValidationFailed( diff --git a/heat/engine/template_files.py b/heat/engine/template_files.py index 93e68b5e6..55a54e0d6 100644 --- a/heat/engine/template_files.py +++ b/heat/engine/template_files.py @@ -28,7 +28,7 @@ class ReadOnlyDict(dict): raise ValueError("Attempted to write to internal TemplateFiles cache") -class TemplateFiles(collections.Mapping): +class TemplateFiles(collections.abc.Mapping): def __init__(self, files): self.files = None diff --git a/heat/tests/openstack/nova/test_server.py b/heat/tests/openstack/nova/test_server.py index f4aec2a81..9b36a533c 100644 --- a/heat/tests/openstack/nova/test_server.py +++ b/heat/tests/openstack/nova/test_server.py @@ -3305,7 +3305,7 @@ class ServersTest(common.HeatTestCase): ws.resource_id = server.id self.patchobject(self.fc.servers, 'get', return_value=server) console_urls = ws._resolve_any_attribute('console_urls') - self.assertIsInstance(console_urls, collections.Mapping) + self.assertIsInstance(console_urls, collections.abc.Mapping) supported_consoles = ('novnc', 'xvpvnc', 'spice-html5', 'rdp-html5', 'serial', 'webmks') self.assertEqual(set(supported_consoles), diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 5bad17671..92e06857c 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -4433,7 +4433,7 @@ class TestResourceMapping(common.HeatTestCase): def _check_mapping_func(self, func, module): self.assertTrue(callable(func)) res = func() - self.assertIsInstance(res, collections.Mapping) + self.assertIsInstance(res, collections.abc.Mapping) for r_type, r_class in res.items(): self.assertIsInstance(r_type, str) type_elements = r_type.split('::') |