Switch to collections.abc.*

The abstract base classes previously defined in 'collections' were moved
to 'collections.abc' in 3.3. The aliases will be removed in 3.10.
Preempt this change now with a simple find-replace:

  $ ag -l 'collections.($TYPES)' | \
      xargs sed -i 's/\(collections\)\.\($TYPES\)/\1.abc.\2/g'

Where $TYPES is the list of moved ABCs from [1].

[1] https://docs.python.org/3/library/collections.abc.html

Change-Id: Ia282479bb1d466bd2189ebb21b51d91e89b9581e
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2021-02-01 09:57:55 +00:00
parent 32f9014207
commit 57e9754093
28 changed files with 123 additions and 116 deletions

View File

@ -248,7 +248,7 @@ the end user.
*AllowedValues(allowed, description)*:
Lists the allowed values. ``allowed`` must be a
``collections.Sequence`` or ``basestring``. Applicable to all types
``collections.abc.Sequence`` or ``basestring``. Applicable to all types
of value except MAP.
*Length(min, max, description)*:
@ -480,16 +480,16 @@ that updates require the engine to delete and re-create the resource
Update the physical resources using updated information.
:param json_snippet: the resource definition from the updated template
:type json_snippet: collections.Mapping
:type json_snippet: collections.abc.Mapping
:param tmpl_diff: values in the updated definition that have changed
with respect to the original template definition.
:type tmpl_diff: collections.Mapping
:type tmpl_diff: collections.abc.Mapping
:param prop_diff: property values that are different between the original
definition and the updated definition; keys are
property names and values are the new values. Deleted or
properties that were originally present but now absent
have values of ``None``
:type prop_diff: collections.Mapping
:type prop_diff: collections.abc.Mapping
*Note* Before calling ``handle_update`` we check whether need to replace
the resource, especially for resource in ``*_FAILED`` state, there is a

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 = {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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