Use None instead of mutables in method params defaults

Mutables in the method params defaults might cause errors and
that's why it's anti-pattern in most of the cases and should be
removed.

Change-Id: I8bc284f12ce72082a0482410ec2c20c2fc087a4b
Closes-Bug: #1327473
This commit is contained in:
liu-sheng 2014-07-01 10:58:22 +08:00
parent b160972b08
commit 5541f43903
30 changed files with 83 additions and 42 deletions

View File

@ -68,7 +68,8 @@ class NeutronExtraRouteTest(HeatTestCase):
resource._register_class("OS::Neutron::ExtraRoute",
extraroute.ExtraRoute)
def create_extraroute(self, t, stack, resource_name, properties={}):
def create_extraroute(self, t, stack, resource_name, properties=None):
properties = properties or {}
t['Resources'][resource_name]['Properties'] = properties
rsrc = extraroute.ExtraRoute(
resource_name,

View File

@ -51,7 +51,7 @@ class FakeManager(object):
def find(self, *args, **kwargs):
pass
def action(self, item, action_type, body={}):
def action(self, item, action_type, body=None):
pass

View File

@ -106,9 +106,11 @@ def get_param_value(params, key):
raise exception.HeatMissingParameterError(key)
def reformat_dict_keys(keymap={}, inputdict={}):
def reformat_dict_keys(keymap=None, inputdict=None):
'''
Utility function for mapping one dict format to another
'''
keymap = keymap or {}
inputdict = inputdict or {}
return dict([(outk, inputdict[ink]) for ink, outk in keymap.items()
if ink in inputdict])

View File

@ -183,13 +183,14 @@ class WatchController(object):
"""
self._enforce(req, 'ListMetrics')
def format_metric_data(d, fil={}):
def format_metric_data(d, fil=None):
"""
Reformat engine output into the AWS "Metric" format
Takes an optional filter dict, which is traversed
so a metric dict is only returned if all keys match
the filter dict
"""
fil = fil or {}
dimensions = [
{'AlarmName': d[engine_api.WATCH_DATA_ALARM]},
{'Timestamp': d[engine_api.WATCH_DATA_TIME]}

View File

@ -34,12 +34,12 @@ class ActionController(object):
self.rpc_client = rpc_client.EngineClient()
@util.identified_stack
def action(self, req, identity, body={}):
def action(self, req, identity, body=None):
"""
Performs a specified action on a stack, the body is expecting to
contain exactly one item whose key specifies the action
"""
body = body or {}
if len(body) < 1:
raise exc.HTTPBadRequest(_("No action specified"))

View File

@ -21,7 +21,8 @@ from heat.rpc import api as engine_api
from heat.rpc import client as rpc_client
def format_resource(req, res, keys=[]):
def format_resource(req, res, keys=None):
keys = keys or []
include_key = lambda k: k in keys if keys else True
def transform(key, value):

View File

@ -80,7 +80,7 @@ class Schema(collections.Mapping):
def __init__(self, data_type, description=None,
default=None, schema=None,
required=False, constraints=[], label=None):
required=False, constraints=None, label=None):
self._len = None
self.label = label
self.type = data_type
@ -108,7 +108,7 @@ class Schema(collections.Mapping):
utype=self.type)
raise InvalidSchemaError(msg)
self.constraints = constraints
self.constraints = constraints or []
self.default = default
def validate(self, context=None):

View File

@ -160,11 +160,12 @@ class Graph(collections.defaultdict):
class Dependencies(object):
'''Helper class for calculating a dependency graph.'''
def __init__(self, edges=[]):
def __init__(self, edges=None):
'''
Initialise, optionally with a list of edges, in the form of
(requirer, required) tuples.
'''
edges = edges or []
self._graph = Graph()
for e in edges:
self += e

View File

@ -54,7 +54,7 @@ class Schema(constr.Schema):
)
def __init__(self, data_type, description=None, default=None, schema=None,
constraints=[], hidden=False, label=None):
constraints=None, hidden=False, label=None):
super(Schema, self).__init__(data_type=data_type,
description=description,
default=default,
@ -403,11 +403,13 @@ class Parameters(collections.Mapping):
'AWS::StackId', 'AWS::StackName', 'AWS::Region'
)
def __init__(self, stack_identifier, tmpl, user_params={}):
def __init__(self, stack_identifier, tmpl, user_params=None):
'''
Create the parameter container for a stack from the stack name and
template, optionally setting the user-supplied parameter values.
'''
user_params = user_params or {}
def user_parameter(schema_item):
name, schema = schema_item
return Parameter(name, schema,

View File

@ -50,7 +50,7 @@ class Schema(constr.Schema):
def __init__(self, data_type, description=None,
default=None, schema=None,
required=False, constraints=[],
required=False, constraints=None,
implemented=True,
update_allowed=False,
support_status=support.SupportStatus()):

View File

@ -264,12 +264,13 @@ class Resource(object):
return identifier.ResourceIdentifier(resource_name=self.name,
**self.stack.identifier())
def parsed_template(self, section=None, default={}):
def parsed_template(self, section=None, default=None):
'''
Return the parsed template data for the resource. May be limited to
only one section of the data, in which case a default value may also
be supplied.
'''
default = default or {}
if section is None:
template = self.t
else:

View File

@ -386,7 +386,7 @@ class InstanceGroup(stack_resource.StackResource):
# nodes.
self._lb_reload()
def _lb_reload(self, exclude=[]):
def _lb_reload(self, exclude=None):
'''
Notify the LoadBalancer to reload its config to include
the changes in instances we have just made.
@ -394,6 +394,7 @@ class InstanceGroup(stack_resource.StackResource):
This must be done after activation (instance in ACTIVE state),
otherwise the instances' IP addresses may not be available.
'''
exclude = exclude or []
if self.properties[self.LOAD_BALANCER_NAMES]:
id_list = [inst.FnGetRefId() for inst in self.get_instances()
if inst.FnGetRefId() not in exclude]

View File

@ -36,7 +36,7 @@ class ResourceDefinitionCore(object):
)
def __init__(self, name, resource_type, properties=None, metadata=None,
depends=[], deletion_policy=None, update_policy=None,
depends=None, deletion_policy=None, update_policy=None,
description=''):
"""
Initialise with the parsed definition of a resource.
@ -53,7 +53,7 @@ class ResourceDefinitionCore(object):
:param update_policy: A dictionary of supplied update policies
:param description: A string describing the resource
"""
depends = depends or []
self.name = name
self.resource_type = resource_type
self.description = description

View File

@ -48,7 +48,7 @@ class WatchRule(object):
updated_at = timestamp.Timestamp(db_api.watch_rule_get, 'updated_at')
def __init__(self, context, watch_name, rule, stack_id=None,
state=NODATA, wid=None, watch_data=[],
state=NODATA, wid=None, watch_data=None,
last_evaluated=timeutils.utcnow()):
self.context = context
self.now = timeutils.utcnow()
@ -63,7 +63,7 @@ class WatchRule(object):
period = int(rule['period'])
self.timeperiod = datetime.timedelta(seconds=period)
self.id = wid
self.watch_data = watch_data
self.watch_data = watch_data or []
self.last_evaluated = last_evaluated
@classmethod

View File

@ -403,7 +403,10 @@ class EngineClient(object):
config_id=config_id))
def create_software_config(self, cnxt, group, name, config,
inputs=[], outputs=[], options={}):
inputs=None, outputs=None, options=None):
inputs = inputs or []
outputs = outputs or []
options = options or {}
return self.call(cnxt, self.make_msg('create_software_config',
group=group,
name=name,
@ -429,9 +432,10 @@ class EngineClient(object):
deployment_id=deployment_id))
def create_software_deployment(self, cnxt, server_id, config_id=None,
input_values={}, action='INIT',
input_values=None, action='INIT',
status='COMPLETE', status_reason='',
stack_user_project_id=None):
input_values = input_values or {}
return self.call(cnxt, self.make_msg(
'create_software_deployment',
server_id=server_id,

View File

@ -61,8 +61,9 @@ class CfnStackControllerTest(HeatTestCase):
'deny_stack_user.json')
self.addCleanup(self.m.VerifyAll)
def _dummy_GET_request(self, params={}):
def _dummy_GET_request(self, params=None):
# Mangle the params dict into a query string
params = params or {}
qs = "&".join(["=".join([k, str(params[k])]) for k in params])
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': qs}
req = Request(environ)

View File

@ -31,8 +31,9 @@ class WatchControllerTest(HeatTestCase):
the endpoint processing API requests after they are routed
'''
def _dummy_GET_request(self, params={}):
def _dummy_GET_request(self, params=None):
# Mangle the params dict into a query string
params = params or {}
qs = "&".join(["=".join([k, str(params[k])]) for k in params])
environ = {'REQUEST_METHOD': 'GET', 'QUERY_STRING': qs}
req = Request(environ)

View File

@ -33,8 +33,10 @@ class Ec2TokenTest(HeatTestCase):
super(Ec2TokenTest, self).setUp()
self.m.StubOutWithMock(requests, 'post')
def _dummy_GET_request(self, params={}, environ={}):
def _dummy_GET_request(self, params=None, environ=None):
# Mangle the params dict into a query string
params = params or {}
environ = environ or {}
qs = "&".join(["=".join([k, str(params[k])]) for k in params])
environ.update({'REQUEST_METHOD': 'GET', 'QUERY_STRING': qs})
req = Request(environ)
@ -179,9 +181,12 @@ class Ec2TokenTest(HeatTestCase):
ec2 = ec2token.EC2Token(app='xyz', conf={})
self.assertEqual('xyz', ec2.__call__(dummy_req))
def _stub_http_connection(self, headers={}, params={}, response=None,
def _stub_http_connection(self, headers=None, params=None, response=None,
req_url='http://123:5000/v2.0/ec2tokens'):
headers = headers or {}
params = params or {}
class DummyHTTPResponse(object):
text = response

View File

@ -2612,7 +2612,9 @@ class EventControllerTest(ControllerTest, HeatTestCase):
class RoutesTest(HeatTestCase):
def assertRoute(self, mapper, path, method, action, controller, params={}):
def assertRoute(self, mapper, path, method, action, controller,
params=None):
params = params or {}
route = mapper.match(path, {'REQUEST_METHOD': method})
self.assertIsNotNone(route)
self.assertEqual(action, route['action'])

View File

@ -185,7 +185,8 @@ class AutoScalingTest(HeatTestCase):
instance.Instance.check_delete_complete(
task).MultipleTimes().AndReturn(True)
def _stub_suspend(self, cookies=[], with_error=None):
def _stub_suspend(self, cookies=None, with_error=None):
cookies = cookies or []
self.m.StubOutWithMock(instance.Instance, 'handle_suspend')
self.m.StubOutWithMock(instance.Instance, 'check_suspend_complete')
if with_error:
@ -200,7 +201,8 @@ class AutoScalingTest(HeatTestCase):
instance.Instance.check_suspend_complete(
cookie).InAnyOrder().AndReturn(True)
def _stub_resume(self, cookies=[], with_error=None):
def _stub_resume(self, cookies=None, with_error=None):
cookies = cookies or []
self.m.StubOutWithMock(instance.Instance, 'handle_resume')
self.m.StubOutWithMock(instance.Instance, 'check_resume_complete')
if with_error:

View File

@ -2622,7 +2622,10 @@ class SoftwareConfigServiceTest(HeatTestCase):
def _create_software_config(
self, group='Heat::Shell', name='config_mysql', config=None,
inputs=[], outputs=[], options={}):
inputs=None, outputs=None, options=None):
inputs = inputs or []
outputs = outputs or []
options = options or {}
return self.engine.create_software_config(
self.ctx, group, name, config, inputs, outputs, options)
@ -2674,13 +2677,14 @@ class SoftwareConfigServiceTest(HeatTestCase):
self.ctx, config_id)
self.assertEqual(ex.exc_info[0], exception.NotFound)
def _create_software_deployment(self, config_id=None, input_values={},
def _create_software_deployment(self, config_id=None, input_values=None,
action='INIT',
status='COMPLETE', status_reason='',
config_group=None,
server_id=str(uuid.uuid4()),
config_name=None,
stack_user_project_id=None):
input_values = input_values or {}
if config_id is None:
config = self._create_software_config(group=config_group,
name=config_name)

View File

@ -889,8 +889,9 @@ class KeystoneClientTest(HeatTestCase):
user_id='duser123', project_id='aproject',
credential_id='acredentialid')
def _stub_uuid(self, values=[]):
def _stub_uuid(self, values=None):
# stub UUID.hex to return the values specified
values = values or []
self.m.StubOutWithMock(uuid, 'uuid4')
for v in values:
mock_uuid = self.m.CreateMockAnything()

View File

@ -136,7 +136,8 @@ class MetadataRefreshTest(HeatTestCase):
# Note tests creating a stack should be decorated with @stack_delete_after
# to ensure the stack is properly cleaned up
def create_stack(self, stack_name='test_stack', params={}):
def create_stack(self, stack_name='test_stack', params=None):
params = params or {}
temp = template_format.parse(test_template_metadata)
template = parser.Template(temp)
ctx = utils.dummy_context()

View File

@ -30,7 +30,8 @@ class MultipartMimeTest(HeatTestCase):
self.ctx = utils.dummy_context()
self.init_config()
def init_config(self, parts=[]):
def init_config(self, parts=None):
parts = parts or []
stack = parser.Stack(
self.ctx, 'software_config_test_stack',
template.Template({

View File

@ -1169,7 +1169,9 @@ class NeutronRouterTest(HeatTestCase):
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def create_router_interface(self, t, stack, resource_name, properties={}):
def create_router_interface(self, t, stack, resource_name,
properties=None):
properties = properties or {}
t['Resources'][resource_name]['Properties'] = properties
resource_defns = stack.t.resource_definitions(stack)
rsrc = router.RouterInterface(
@ -1180,7 +1182,8 @@ class NeutronRouterTest(HeatTestCase):
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def create_gateway_router(self, t, stack, resource_name, properties={}):
def create_gateway_router(self, t, stack, resource_name, properties=None):
properties = properties or {}
t['Resources'][resource_name]['Properties'] = properties
resource_defns = stack.t.resource_definitions(stack)
rsrc = router.RouterGateway(

View File

@ -116,7 +116,8 @@ Resources:
stack.store()
return stack
def assertResourceState(self, rsrc, ref_id, metadata={}):
def assertResourceState(self, rsrc, ref_id, metadata=None):
metadata = metadata or {}
self.assertIsNone(rsrc.validate())
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(ref_id, rsrc.FnGetRefId())

View File

@ -361,8 +361,9 @@ params_schema = json.loads('''{
class ParametersTest(testtools.TestCase):
def new_parameters(self, stack_name, tmpl, user_params={}, stack_id=None,
validate_value=True):
def new_parameters(self, stack_name, tmpl, user_params=None,
stack_id=None, validate_value=True):
user_params = user_params or {}
tmpl.update({'HeatTemplateFormatVersion': '2012-12-12'})
tmpl = template.Template(tmpl)
params = tmpl.parameters(

View File

@ -156,7 +156,8 @@ Resources:
stack.store()
return stack
def assertResourceState(self, rsrc, ref_id, metadata={}):
def assertResourceState(self, rsrc, ref_id, metadata=None):
metadata = metadata or {}
self.assertIsNone(rsrc.validate())
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual(ref_id, rsrc.FnGetRefId())

View File

@ -109,8 +109,9 @@ class WaitConditionTest(HeatTestCase):
# Note tests creating a stack should be decorated with @stack_delete_after
# to ensure the stack is properly cleaned up
def create_stack(self, stack_id=None,
template=test_template_waitcondition, params={},
template=test_template_waitcondition, params=None,
stub=True):
params = params or {}
temp = template_format.parse(template)
template = parser.Template(temp)
ctx = utils.dummy_context(tenant_id='test_tenant')

View File

@ -65,7 +65,8 @@ def reset_dummy_db():
def dummy_context(user='test_username', tenant_id='test_tenant_id',
password='password', roles=[], user_id=None):
password='password', roles=None, user_id=None):
roles = roles or []
return context.RequestContext.from_dict({
'tenant_id': tenant_id,
'tenant': 'test_tenant',
@ -79,8 +80,9 @@ def dummy_context(user='test_username', tenant_id='test_tenant_id',
})
def parse_stack(t, params={}, stack_name='test_stack', stack_id=None,
def parse_stack(t, params=None, stack_name='test_stack', stack_id=None,
timeout_mins=None):
params = params or {}
ctx = dummy_context()
template = parser.Template(t)
stack = parser.Stack(ctx, stack_name, template,