Get rid of gratuitous use of six.iterkeys()

In Python3, dict.keys() returns a view object rather than a list. This
behaves differently in that changes to the dict also modify the view, and
in that the view type interacts with various operators in different ways to
lists.

One universally correct transformation to preserve Python2 behaviour in
Python3 would be to replace all instances of d.keys() with
list(six.iterkeys(d)), and indeed we did. However, like many automatic
transformations the results are usually unsightly, invariably inefficient,
and frequently absurd. Not least because list(d.keys()) and indeed list(d)
are also equivalent.

This patch changes to using the simplest correct method of accessing the
data we want in each case.

This reverts or rewrites most of commit
4ace95ad47.

Change-Id: Iba3cf48246d8cbc958d8fb577cd700a218b0bebf
This commit is contained in:
Zane Bitter 2016-05-31 12:45:58 -04:00 committed by Rabi Mishra
parent e1a6c072a1
commit 5566e6f2c8
26 changed files with 83 additions and 97 deletions

View File

@ -801,7 +801,7 @@ class CloudLoadBalancer(resource.Resource):
old_props = {}
new_props = {}
for prop in six.iterkeys(prop_diff):
for prop in prop_diff:
if prop in self.LB_UPDATE_PROPS:
old_props[prop] = getattr(lb, prop)
new_props[prop] = prop_diff[prop]
@ -831,8 +831,8 @@ class CloudLoadBalancer(resource.Resource):
node[self.NODE_PORT]), node)
for node in diff_nodes)
old_set = set(six.iterkeys(old))
new_set = set(six.iterkeys(new))
old_set = set(old)
new_set = set(new)
deleted = old_set.difference(new_set)
added = new_set.difference(old_set)
@ -900,8 +900,7 @@ class CloudLoadBalancer(resource.Resource):
for node in updated:
node_changed = False
for attribute in six.iterkeys(new[node]):
new_value = new[node][attribute]
for attribute, new_value in new[node].items():
if new_value and new_value != getattr(old[node], attribute):
node_changed = True
setattr(old[node], attribute, new_value)

View File

@ -1379,7 +1379,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_health_monitor_delete(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
hm = {'type': "HTTP", 'delay': 10, 'timeout': 10,
'attemptsBeforeDeactivation': 4, 'path': "/",
'statusRegex': "^[234][0-9][0-9]$", 'bodyRegex': ".* testing .*",
@ -1433,7 +1433,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_session_persistence_delete(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties'][
'sessionPersistence'] = "SOURCE_IP"
expected_body = copy.deepcopy(self.expected_body)
@ -1493,7 +1493,7 @@ class LoadBalancerTest(common.HeatTestCase):
'securePort': 443, 'privatekey': private_key, 'certificate': cert,
'intermediateCertificate': '', 'secureTrafficOnly': False}
ssl_termination_api = copy.deepcopy(ssl_termination_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties']['sslTermination'] = (
ssl_termination_template)
# The SSL termination config is done post-creation, so no need
@ -1563,7 +1563,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_metadata_delete(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties']['metadata'] = {
'a': 1, 'b': 2}
expected_body = copy.deepcopy(self.expected_body)
@ -1622,7 +1622,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_errorpage_delete(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
error_page = (
'<html><head><title>Service Unavailable</title></head><body><h2>'
'Service Unavailable</h2>The service is unavailable</body></html>')
@ -1685,7 +1685,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_connection_logging_delete(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties'][
'connectionLogging'] = True
expected_body = copy.deepcopy(self.expected_body)
@ -1718,7 +1718,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_connection_logging_disable(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties'][
'connectionLogging'] = True
expected_body = copy.deepcopy(self.expected_body)
@ -1773,7 +1773,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_connection_throttle_delete(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties'][
'connectionThrottle'] = {'maxConnections': 1000}
expected_body = copy.deepcopy(self.expected_body)
@ -1833,7 +1833,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_content_caching_deleted(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties'][
'contentCaching'] = 'ENABLED'
# Enabling the content cache is done post-creation, so no need
@ -1864,7 +1864,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_content_caching_disable(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
template['Resources'][lb_name]['Properties'][
'contentCaching'] = 'ENABLED'
# Enabling the content cache is done post-creation, so no need
@ -2168,7 +2168,7 @@ class LoadBalancerTest(common.HeatTestCase):
def test_update_nodes_defaults(self):
template = copy.deepcopy(self.lb_template)
lb_name = list(six.iterkeys(template['Resources']))[0]
lb_name = next(iter(template['Resources']))
tmpl_node = template['Resources'][lb_name]['Properties']['nodes'][0]
tmpl_node['type'] = "PRIMARY"
tmpl_node['condition'] = "ENABLED"

View File

@ -163,7 +163,7 @@ class ResourcePages(compat.Directive):
def contribute_hot_syntax(self, parent):
section = self._section(parent, _('HOT Syntax'), '%s-hot')
props = []
for prop_key in sorted(six.iterkeys(self.props_schemata)):
for prop_key in sorted(self.props_schemata.keys()):
prop = self.props_schemata[prop_key]
if (prop.implemented
and prop.support_status.status == support.SUPPORTED):
@ -363,7 +363,7 @@ def _filter_resources(prefix=None, path=None, statuses=None):
statuses = statuses or []
filtered_resources = {}
for name in sorted(six.iterkeys(all_resources)):
for name in sorted(all_resources.keys()):
if prefix_match(name):
for cls in all_resources.get(name):
if (path_match(cls) and status_match(cls) and

View File

@ -66,8 +66,8 @@ class WatchController(object):
"""
newdims = []
for count, d in enumerate(dims, 1):
for key in six.iterkeys(d):
newdims.append({'Name': key, 'Value': d[key]})
for key, value in d.items():
newdims.append({'Name': key, 'Value': value})
return newdims
def delete_alarms(self, req):
@ -302,7 +302,7 @@ class WatchController(object):
msg = _('Invalid state %(state)s, '
'expecting one of %(expect)s') % {
'state': state,
'expect': list(six.iterkeys(state_map))}
'expect': list(state_map.keys())}
LOG.error(msg)
return exception.HeatInvalidParameterValueError(msg)

View File

@ -290,7 +290,7 @@ def format_resource_attributes(resource, with_attr=None):
# including the ones are not represented in response of show API, such as
# 'console_urls' for nova server, user can view it by taking with_attr
# parameter
if 'show' in six.iterkeys(resolver):
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):
@ -302,7 +302,7 @@ def format_resource_attributes(resource, with_attr=None):
# remove 'show' attribute if it's None or not a mapping
# then resolve all attributes manually
del resolver._attributes['show']
attributes = set(list(six.iterkeys(resolver)) + with_attr)
attributes = set(resolver) | set(with_attr)
return dict((attr, resolve(attr, resolver))
for attr in attributes)
@ -315,7 +315,7 @@ def format_resource_properties(resource):
return None
return dict((prop, get_property(prop))
for prop in six.iterkeys(resource.properties_schema))
for prop in resource.properties_schema.keys())
def format_stack_resource(resource, detail=True, with_props=False,

View File

@ -221,7 +221,7 @@ class GetAtt(function.Function):
attr = function.resolve(self._attribute)
from heat.engine import resource
if (type(res).get_attribute == resource.Resource.get_attribute and
attr not in six.iterkeys(res.attributes_schema)):
attr not in res.attributes_schema):
raise exception.InvalidTemplateAttribute(
resource=self._resource_name, key=attr)

View File

@ -155,8 +155,7 @@ class CfnTemplate(template.Template):
deletion_policy = function.resolve(data.get(RES_DELETION_POLICY))
if deletion_policy is not None:
if deletion_policy not in six.iterkeys(
self.deletion_policies):
if deletion_policy not in self.deletion_policies:
msg = _('Invalid deletion policy "%s"') % deletion_policy
raise exception.StackValidationFailed(message=msg)
else:

View File

@ -535,8 +535,7 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
"""Delete/Add the metadata in nova as needed."""
metadata = self.meta_serialize(metadata)
current_md = server.metadata
to_del = sorted([key for key in six.iterkeys(current_md)
if key not in metadata])
to_del = sorted(set(current_md) - set(metadata))
client = self.client()
if len(to_del) > 0:
client.servers.delete_meta(server, to_del)

View File

@ -306,8 +306,8 @@ class ResourceRegistry(object):
if info is None:
if name.endswith('*'):
# delete all matching entries.
for res_name in list(six.iterkeys(registry)):
if (isinstance(registry[res_name], ResourceInfo) and
for res_name, reg_info in list(registry.items()):
if (isinstance(reg_info, ResourceInfo) and
res_name.startswith(name[:-1])):
LOG.warning(_LW('Removing %(item)s from %(path)s'), {
'item': res_name,
@ -469,7 +469,7 @@ class ResourceRegistry(object):
# handle: "OS::*" -> "Dreamhost::*"
def is_a_glob(resource_type):
return resource_type.endswith('*')
globs = six.moves.filter(is_a_glob, six.iterkeys(self._registry))
globs = six.moves.filter(is_a_glob, iter(self._registry))
for pattern in globs:
if self._registry[pattern].matches(resource_type):
yield self._registry[pattern]

View File

@ -501,9 +501,9 @@ class Parameters(collections.Mapping):
self.non_pseudo_param_keys = [p for p in self.params if p not in
self.PSEUDO_PARAMETERS]
for pd in six.iterkeys(param_defaults):
if pd in self.params:
self.params[pd].set_default(param_defaults[pd])
for pd_name, param_default in param_defaults.items():
if pd_name in self.params:
self.params[pd_name].set_default(param_default)
def validate(self, validate_value=True, context=None):
"""Validates all parameters.

View File

@ -12,7 +12,6 @@
# under the License.
import copy
import six
import uuid
from oslo_config import cfg
@ -636,7 +635,7 @@ class SoftwareDeploymentGroup(resource_group.ResourceGroup):
return len(self.properties.get(self.SERVERS, {}))
def _resource_names(self):
return six.iterkeys(self.properties.get(self.SERVERS, {}))
return iter(self.properties.get(self.SERVERS, {}))
def get_resource_def(self, include_all=False):
return dict(self.properties)

View File

@ -380,7 +380,7 @@ class Workflow(signal_responder.SignalResponder,
raise exception.StackValidationFailed(
error=_('Signal data error'),
message=message)
for key in six.iterkeys(inputs):
for key in inputs:
if (self.properties.get(self.INPUT) is None or
key not in self.properties.get(self.INPUT)):
message = _('Unknown input %s') % key

View File

@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.common import exception
from heat.common.i18n import _
from heat.engine import attributes
@ -780,7 +778,7 @@ class LoadBalancer(resource.Resource):
new_props[self.MEMBERS] is not None)):
members = set(new_props[self.MEMBERS] or [])
rd_members = self.data()
old_members = set(six.iterkeys(rd_members))
old_members = set(rd_members)
for member in old_members - members:
member_id = rd_members[member]
with self.client_plugin().ignore_not_found:

View File

@ -10,7 +10,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.common import exception
from heat.common.i18n import _
@ -38,12 +37,11 @@ class NeutronResource(resource.Resource):
Also ensures that shared and tenant_id is not specified
in value_specs.
"""
if 'value_specs' in six.iterkeys(properties):
vs = properties.get('value_specs')
banned_keys = set(['shared', 'tenant_id']).union(
six.iterkeys(properties))
for k in banned_keys.intersection(six.iterkeys(vs)):
return '%s not allowed in value_specs' % k
if 'value_specs' in properties:
banned_keys = set(['shared', 'tenant_id']).union(set(properties))
found = banned_keys.intersection(set(properties['value_specs']))
if found:
return '%s not allowed in value_specs' % ', '.join(found)
@staticmethod
def prepare_properties(properties, name):
@ -58,7 +56,7 @@ class NeutronResource(resource.Resource):
props = dict((k, v) for k, v in properties.items()
if v is not None)
if 'name' in six.iterkeys(properties):
if 'name' in properties:
props.setdefault('name', name)
if 'value_specs' in props:

View File

@ -233,13 +233,13 @@ class Cluster(resource.Resource):
if not updaters:
return True
for k in six.iterkeys(updaters):
if not updaters[k]['start']:
action_id = start_action(k, updaters[k]['params'])
updaters[k]['action'] = action_id
updaters[k]['start'] = True
for k, updater in list(updaters.items()):
if not updater['start']:
action_id = start_action(k, updater['params'])
updater['action'] = action_id
updater['start'] = True
else:
action = self.client().get_action(updaters[k]['action'])
action = self.client().get_action(updater['action'])
if action.status == self.ACTION_SUCCEEDED:
del updaters[k]
elif action.status == self.ACTION_FAILED:

View File

@ -748,8 +748,7 @@ class Stack(collections.Mapping):
self.t.validate_resource_definitions(self)
# Check duplicate names between parameters and resources
dup_names = (set(six.iterkeys(self.parameters)) &
set(six.iterkeys(self)))
dup_names = set(self.parameters) & set(self.keys())
if dup_names:
LOG.debug("Duplicate names %s" % dup_names)

View File

@ -66,7 +66,7 @@ class TemplatePluginNotRegistered(exception.HeatException):
def get_template_class(template_data):
available_versions = list(six.iterkeys(_template_classes))
available_versions = _template_classes.keys()
version = get_version(template_data, available_versions)
version_type = version[0]
try:
@ -114,8 +114,7 @@ class Template(collections.Mapping):
self.maps = self[self.MAPPINGS]
self.env = env or environment.Environment({})
self.version = get_version(self.t,
list(six.iterkeys(_template_classes)))
self.version = get_version(self.t, _template_classes.keys())
self.t_digest = None
def __deepcopy__(self, memo):
@ -257,7 +256,7 @@ class Template(collections.Mapping):
return
# check top-level sections
for k in six.iterkeys(self.t):
for k in self.t.keys():
if k not in self.SECTIONS:
raise exception.InvalidTemplateSection(section=k)

View File

@ -12,7 +12,6 @@
# under the License.
import os
import six
from oslo_config import fixture as config_fixture
@ -500,7 +499,7 @@ class WatchControllerTest(common.HeatTestCase):
'ALARM': rpc_api.WATCH_STATE_ALARM,
'INSUFFICIENT_DATA': rpc_api.WATCH_STATE_NODATA}
for state in six.iterkeys(state_map):
for state in state_map:
params = {u'StateValue': state,
u'StateReason': u'',
u'AlarmName': u'HttpFailureAlarm',

View File

@ -13,7 +13,6 @@
import mock
from oslo_config import cfg
import six
from heat.common import exception
from heat.common import short_id
@ -346,7 +345,7 @@ class AccessKeyTest(common.HeatTestCase):
rs_data = resource_data_object.ResourceData.get_all(rsrc)
self.assertEqual(self.fc.secret, rs_data.get('secret_key'))
self.assertEqual(self.fc.credential_id, rs_data.get('credential_id'))
self.assertEqual(2, len(list(six.iterkeys(rs_data))))
self.assertEqual(2, len(rs_data.keys()))
self.assertEqual(utils.PhysName(stack.name, 'CfnUser'),
rsrc.FnGetAtt('UserName'))

View File

@ -18,7 +18,6 @@ import mock
from novaclient import client as base_client
from novaclient import exceptions as nova_exceptions
import requests
import six
from six.moves.urllib import parse as urlparse
from heat.tests import fakes
@ -245,19 +244,19 @@ class FakeHTTPClient(base_client.HTTPClient):
def post_servers_1234_action(self, body, **kw):
_body = None
resp = 202
assert len(list(six.iterkeys(body))) == 1
action = list(six.iterkeys(body))[0]
assert len(body.keys()) == 1
action = next(iter(body))
if action == 'reboot':
assert list(six.iterkeys(body[action])) == ['type']
assert list(body[action].keys()) == ['type']
assert body[action]['type'] in ['HARD', 'SOFT']
elif action == 'rebuild':
keys = list(six.iterkeys(body[action]))
keys = list(body[action].keys())
if 'adminPass' in keys:
keys.remove('adminPass')
assert keys == ['imageRef']
_body = self.get_servers_1234()[1]
elif action == 'resize':
assert list(six.iterkeys(body[action])) == ['flavorRef']
assert list(body[action].keys()) == ['flavorRef']
elif action == 'confirmResize':
assert body[action] is None
# This one method returns a different response code
@ -270,27 +269,27 @@ class FakeHTTPClient(base_client.HTTPClient):
]:
assert body[action] is None
elif action == 'addFixedIp':
assert list(six.iterkeys(body[action])) == ['networkId']
assert list(body[action].keys()) == ['networkId']
elif action in ['removeFixedIp',
'addFloatingIp',
'removeFloatingIp',
]:
assert list(six.iterkeys(body[action])) == ['address']
assert list(body[action].keys()) == ['address']
elif action == 'createImage':
assert set(six.iterkeys(body[action])) == set(['name', 'metadata'])
assert set(body[action].keys()) == set(['name', 'metadata'])
resp = {"status": 202,
"location": "http://blah/images/456"}
elif action == 'changePassword':
assert list(six.iterkeys(body[action])) == ['adminPass']
assert list(body[action].keys()) == ['adminPass']
elif action == 'os-getConsoleOutput':
assert list(six.iterkeys(body[action])) == ['length']
assert list(body[action].keys()) == ['length']
return (202, {'output': 'foo'})
elif action == 'os-getVNCConsole':
assert list(six.iterkeys(body[action])) == ['type']
assert list(body[action].keys()) == ['type']
elif action == 'os-migrateLive':
assert set(six.iterkeys(body[action])) == set(['host',
'block_migration',
'disk_over_commit'])
assert set(body[action].keys()) == set(['host',
'block_migration',
'disk_over_commit'])
else:
raise AssertionError("Unexpected server action: %s" % action)
return (resp, _body)
@ -298,8 +297,8 @@ class FakeHTTPClient(base_client.HTTPClient):
def post_servers_5678_action(self, body, **kw):
_body = None
resp = 202
assert len(list(six.iterkeys(body))) == 1
action = list(six.iterkeys(body))[0]
assert len(body.keys()) == 1
action = next(iter(body))
if action in ['addFloatingIp',
'removeFloatingIp',
]:

View File

@ -2863,7 +2863,7 @@ class ServersTest(common.HeatTestCase):
supported_consoles = ('novnc', 'xvpvnc', 'spice-html5', 'rdp-html5',
'serial')
self.assertEqual(set(supported_consoles),
set(six.iterkeys(console_urls)))
set(console_urls))
def test_resolve_attribute_networks(self):
return_server = self.fc.servers.list()[1]

View File

@ -88,10 +88,10 @@ class FormatTest(common.HeatTestCase):
)))
formatted = api.format_stack_resource(res, True)
self.assertEqual(resource_details_keys, set(six.iterkeys(formatted)))
self.assertEqual(resource_details_keys, set(formatted.keys()))
formatted = api.format_stack_resource(res, False)
self.assertEqual(resource_keys, set(six.iterkeys(formatted)))
self.assertEqual(resource_keys, set(formatted.keys()))
self.assertEqual(self.stack.created_time.isoformat(),
formatted[rpc_api.RES_CREATION_TIME])
self.assertEqual(self.stack.updated_time.isoformat(),
@ -232,7 +232,7 @@ class FormatTest(common.HeatTestCase):
rpc_api.RES_REQUIRED_BY))
formatted = api.format_stack_resource(res, False)
self.assertEqual(resource_keys, set(six.iterkeys(formatted)))
self.assertEqual(resource_keys, set(formatted.keys()))
def test_format_stack_resource_with_nested_stack_not_found(self):
res = self.stack['generic4']
@ -255,7 +255,7 @@ class FormatTest(common.HeatTestCase):
formatted = api.format_stack_resource(res, False)
# 'nested_stack_id' is not in formatted
self.assertEqual(resource_keys, set(six.iterkeys(formatted)))
self.assertEqual(resource_keys, set(formatted.keys()))
def test_format_stack_resource_with_nested_stack_empty(self):
res = self.stack['generic4']
@ -300,7 +300,7 @@ class FormatTest(common.HeatTestCase):
rpc_api.EVENT_RES_PROPERTIES))
formatted = api.format_event(event)
self.assertEqual(event_keys, set(six.iterkeys(formatted)))
self.assertEqual(event_keys, set(formatted.keys()))
event_id_formatted = formatted[rpc_api.EVENT_ID]
event_identifier = identifier.EventIdentifier(

View File

@ -1158,7 +1158,7 @@ class HOTemplateTest(common.HeatTestCase):
{'foo': {'Type': 'String',
'Required': True}}})
self.assertEqual(expected_description, tmpl['description'])
self.assertNotIn('parameters', six.iterkeys(tmpl))
self.assertNotIn('parameters', tmpl.keys())
def test_invalid_hot_version(self):
"""Test HOT version check.
@ -1241,7 +1241,7 @@ class HOTemplateTest(common.HeatTestCase):
self.resolve,
snippet,
stack.t, stack)
self.assertIn(list(six.iterkeys(snippet))[0], six.text_type(error))
self.assertIn(next(iter(snippet)), six.text_type(error))
def test_resource_facade_missing_deletion_policy(self):
snippet = {'resource_facade': 'deletion_policy'}
@ -1266,7 +1266,7 @@ class HOTemplateTest(common.HeatTestCase):
error = self.assertRaises(exception.InvalidTemplateVersion,
function.validate,
stack.t.parse(stack, snippet))
self.assertIn(next(six.iterkeys(snippet)), six.text_type(error))
self.assertIn(next(iter(snippet)), six.text_type(error))
def test_add_resource(self):
hot_tpl = template_format.parse('''

View File

@ -121,7 +121,7 @@ class SignalTest(common.HeatTestCase):
self.assertEqual('verysecret', rs_data.get('secret_key'))
self.assertEqual('1234', rs_data.get('user_id'))
self.assertEqual(rsrc.resource_id, rs_data.get('user_id'))
self.assertEqual(4, len(list(six.iterkeys(rs_data))))
self.assertEqual(4, len(rs_data))
def test_get_user_id(self):
# Setup

View File

@ -897,7 +897,7 @@ class TemplateTest(common.HeatTestCase):
template.Template(empty_template))
error = self.assertRaises(ValueError,
self.resolve, snippet, stk.t, stk)
self.assertIn(list(six.iterkeys(snippet))[0], six.text_type(error))
self.assertIn(next(iter(snippet)), six.text_type(error))
def test_resource_facade_missing_deletion_policy(self):
snippet = {'Fn::ResourceFacade': 'DeletionPolicy'}
@ -937,7 +937,7 @@ class TemplateTest(common.HeatTestCase):
}
})
self.assertEqual(expected_description, tmpl['Description'])
self.assertNotIn('Parameters', six.iterkeys(tmpl))
self.assertNotIn('Parameters', tmpl.keys())
def test_add_resource(self):
cfn_tpl = template_format.parse('''
@ -1158,8 +1158,7 @@ class TemplateFnErrorTest(common.HeatTestCase):
error = self.assertRaises(self.expect,
resolve,
self.snippet)
self.assertIn(list(six.iterkeys(self.snippet))[0],
six.text_type(error))
self.assertIn(next(iter(self.snippet)), six.text_type(error))
class ResolveDataTest(common.HeatTestCase):

View File

@ -202,7 +202,7 @@ class JsonYamlResolvedCompareTest(common.HeatTestCase):
del(t2nr['Resources'])
self.assertEqual(t1nr, t2nr)
self.assertEqual(set(six.iterkeys(stack1)), set(six.iterkeys(stack2)))
self.assertEqual(set(stack1), set(stack2))
for key in stack1:
self.assertEqual(stack1[key].t, stack2[key].t)