Replace copy.copy with copy.deepcopy

The function copy.copy only copies reference and so if the object has dict
or nested dicts, these instances can be modified by code that has reference
to the original dict.

Change-Id: Ib2680f09b5a5d45fd7180e95ab5fedef05664c5b
Closes-Bug: #1503851
This commit is contained in:
Winson Chan 2015-10-07 19:55:31 +00:00
parent 107cd6c5cb
commit 55540e116e
14 changed files with 32 additions and 32 deletions

View File

@ -466,7 +466,7 @@ class DefaultEngine(base.Engine, coordination.Service):
'state': states.RUNNING, 'state': states.RUNNING,
'input': wf_input or {}, 'input': wf_input or {},
'output': {}, 'output': {},
'context': copy.copy(wf_input) or {}, 'context': copy.deepcopy(wf_input) or {},
'task_execution_id': params.get('task_execution_id'), 'task_execution_id': params.get('task_execution_id'),
'runtime_context': { 'runtime_context': {
'with_items_index': params.get('with_items_index', 0) 'with_items_index': params.get('with_items_index', 0)

View File

@ -405,7 +405,7 @@ def _schedule_run_action(task_ex, task_spec, action_input, index):
task_spec.get_target(), task_spec.get_target(),
utils.merge_dicts( utils.merge_dicts(
copy.deepcopy(action_input), copy.deepcopy(action_input),
copy.copy(task_ex.in_context) copy.deepcopy(task_ex.in_context)
) )
) )

View File

@ -26,7 +26,7 @@ LOG = logging.getLogger(__name__)
def validate_input(definition, input, spec=None): def validate_input(definition, input, spec=None):
input_param_names = copy.copy(list((input or {}).keys())) input_param_names = copy.deepcopy(list((input or {}).keys()))
missing_param_names = [] missing_param_names = []
spec_input = (spec.get_input() if spec else spec_input = (spec.get_input() if spec else

View File

@ -193,7 +193,7 @@ def _evaluate_item(item, context):
def evaluate_recursively(data, context): def evaluate_recursively(data, context):
data = copy.copy(data) data = copy.deepcopy(data)
if not context: if not context:
return data return data

View File

@ -142,7 +142,7 @@ class CallScheduler(periodic_task.PeriodicTasks):
call.target_method_name call.target_method_name
) )
method_args = copy.copy(call.method_arguments) method_args = copy.deepcopy(call.method_arguments)
if call.serializers: if call.serializers:
# Deserialize arguments. # Deserialize arguments.

View File

@ -95,18 +95,18 @@ ACTION_EX = {
UPDATED_ACTION_EX_DB = copy.copy(ACTION_EX_DB).to_dict() UPDATED_ACTION_EX_DB = copy.copy(ACTION_EX_DB).to_dict()
UPDATED_ACTION_EX_DB['state'] = 'SUCCESS' UPDATED_ACTION_EX_DB['state'] = 'SUCCESS'
UPDATED_ACTION_EX_DB['task_name'] = 'task1' UPDATED_ACTION_EX_DB['task_name'] = 'task1'
UPDATED_ACTION = copy.copy(ACTION_EX) UPDATED_ACTION = copy.deepcopy(ACTION_EX)
UPDATED_ACTION['state'] = 'SUCCESS' UPDATED_ACTION['state'] = 'SUCCESS'
UPDATED_ACTION_OUTPUT = UPDATED_ACTION['output'] UPDATED_ACTION_OUTPUT = UPDATED_ACTION['output']
ERROR_ACTION_EX = copy.copy(ACTION_EX_DB).to_dict() ERROR_ACTION_EX = copy.copy(ACTION_EX_DB).to_dict()
ERROR_ACTION_EX['state'] = 'ERROR' ERROR_ACTION_EX['state'] = 'ERROR'
ERROR_ACTION_EX['task_name'] = 'task1' ERROR_ACTION_EX['task_name'] = 'task1'
ERROR_ACTION = copy.copy(ACTION_EX) ERROR_ACTION = copy.deepcopy(ACTION_EX)
ERROR_ACTION['state'] = 'ERROR' ERROR_ACTION['state'] = 'ERROR'
ERROR_ACTION_RES = ERROR_ACTION['output'] ERROR_ACTION_RES = ERROR_ACTION['output']
BROKEN_ACTION = copy.copy(ACTION_EX) BROKEN_ACTION = copy.deepcopy(ACTION_EX)
BROKEN_ACTION['output'] = 'string not escaped' BROKEN_ACTION['output'] = 'string not escaped'
MOCK_ACTION = mock.MagicMock(return_value=ACTION_EX_DB) MOCK_ACTION = mock.MagicMock(return_value=ACTION_EX_DB)
@ -257,7 +257,7 @@ class TestActionExecutionsController(base.FunctionalTest):
@mock.patch.object(rpc.EngineClient, 'on_action_complete') @mock.patch.object(rpc.EngineClient, 'on_action_complete')
def test_put_without_result(self, f): def test_put_without_result(self, f):
action_ex = copy.copy(UPDATED_ACTION) action_ex = copy.deepcopy(UPDATED_ACTION)
del action_ex['output'] del action_ex['output']
f.return_value = UPDATED_ACTION_EX_DB f.return_value = UPDATED_ACTION_EX_DB

View File

@ -81,7 +81,7 @@ my_action:
UPDATED_ACTION_DB = copy.copy(ACTION_DB) UPDATED_ACTION_DB = copy.copy(ACTION_DB)
UPDATED_ACTION_DB['definition'] = UPDATED_ACTION_DEFINITION UPDATED_ACTION_DB['definition'] = UPDATED_ACTION_DEFINITION
UPDATED_ACTION = copy.copy(ACTION) UPDATED_ACTION = copy.deepcopy(ACTION)
UPDATED_ACTION['definition'] = UPDATED_ACTION_DEFINITION UPDATED_ACTION['definition'] = UPDATED_ACTION_DEFINITION
MOCK_ACTION = mock.MagicMock(return_value=ACTION_DB) MOCK_ACTION = mock.MagicMock(return_value=ACTION_DB)

View File

@ -47,7 +47,7 @@ TRIGGER = {
'remaining_executions': 42 'remaining_executions': 42
} }
trigger_values = copy.copy(TRIGGER) trigger_values = copy.deepcopy(TRIGGER)
trigger_values['workflow_input'] = json.loads( trigger_values['workflow_input'] = json.loads(
trigger_values['workflow_input']) trigger_values['workflow_input'])
@ -61,7 +61,7 @@ TRIGGER_DB.update(trigger_values)
UPDATED_TRIGGER_DB = copy.copy(TRIGGER_DB) UPDATED_TRIGGER_DB = copy.copy(TRIGGER_DB)
UPDATED_TRIGGER_DB['pattern'] = '*/1 * * * *' UPDATED_TRIGGER_DB['pattern'] = '*/1 * * * *'
UPDATED_TRIGGER = copy.copy(TRIGGER) UPDATED_TRIGGER = copy.deepcopy(TRIGGER)
UPDATED_TRIGGER['pattern'] = '*/1 * * * *' UPDATED_TRIGGER['pattern'] = '*/1 * * * *'
MOCK_WF = mock.MagicMock(return_value=WF) MOCK_WF = mock.MagicMock(return_value=WF)

View File

@ -54,13 +54,13 @@ WF_EX_JSON = {
'workflow_name': 'some', 'workflow_name': 'some',
} }
UPDATED_WF_EX = copy.copy(WF_EX) UPDATED_WF_EX = copy.deepcopy(WF_EX)
UPDATED_WF_EX['state'] = states.PAUSED UPDATED_WF_EX['state'] = states.PAUSED
UPDATED_WF_EX_JSON = copy.copy(WF_EX_JSON) UPDATED_WF_EX_JSON = copy.deepcopy(WF_EX_JSON)
UPDATED_WF_EX_JSON['state'] = states.PAUSED UPDATED_WF_EX_JSON['state'] = states.PAUSED
WF_EX_JSON_WITH_DESC = copy.copy(WF_EX_JSON) WF_EX_JSON_WITH_DESC = copy.deepcopy(WF_EX_JSON)
WF_EX_JSON_WITH_DESC['description'] = "execution description." WF_EX_JSON_WITH_DESC['description'] = "execution description."
MOCK_WF_EX = mock.MagicMock(return_value=WF_EX) MOCK_WF_EX = mock.MagicMock(return_value=WF_EX)
@ -98,7 +98,7 @@ class TestExecutionsController(base.FunctionalTest):
def test_put(self): def test_put(self):
resp = self.app.put_json('/v2/executions/123', UPDATED_WF_EX_JSON) resp = self.app.put_json('/v2/executions/123', UPDATED_WF_EX_JSON)
UPDATED_WF_EX_WITH_DESC = copy.copy(UPDATED_WF_EX_JSON) UPDATED_WF_EX_WITH_DESC = copy.deepcopy(UPDATED_WF_EX_JSON)
UPDATED_WF_EX_WITH_DESC['description'] = 'execution description.' UPDATED_WF_EX_WITH_DESC['description'] = 'execution description.'
self.assertEqual(200, resp.status_int) self.assertEqual(200, resp.status_int)
@ -110,12 +110,12 @@ class TestExecutionsController(base.FunctionalTest):
MOCK_WF_EX MOCK_WF_EX
) )
def test_put_stop(self): def test_put_stop(self):
update_exec = copy.copy(WF_EX_JSON) update_exec = copy.deepcopy(WF_EX_JSON)
update_exec['state'] = states.ERROR update_exec['state'] = states.ERROR
update_exec['state_info'] = "Force" update_exec['state_info'] = "Force"
with mock.patch.object(rpc.EngineClient, 'stop_workflow') as mock_pw: with mock.patch.object(rpc.EngineClient, 'stop_workflow') as mock_pw:
wf_ex = copy.copy(WF_EX) wf_ex = copy.deepcopy(WF_EX)
wf_ex['state'] = states.ERROR wf_ex['state'] = states.ERROR
wf_ex['state_info'] = "Force" wf_ex['state_info'] = "Force"
mock_pw.return_value = wf_ex mock_pw.return_value = wf_ex
@ -134,12 +134,12 @@ class TestExecutionsController(base.FunctionalTest):
MOCK_WF_EX MOCK_WF_EX
) )
def test_put_state_info_unset(self): def test_put_state_info_unset(self):
update_exec = copy.copy(WF_EX_JSON) update_exec = copy.deepcopy(WF_EX_JSON)
update_exec['state'] = states.ERROR update_exec['state'] = states.ERROR
update_exec.pop('state_info', None) update_exec.pop('state_info', None)
with mock.patch.object(rpc.EngineClient, 'stop_workflow') as mock_pw: with mock.patch.object(rpc.EngineClient, 'stop_workflow') as mock_pw:
wf_ex = copy.copy(WF_EX) wf_ex = copy.deepcopy(WF_EX)
wf_ex['state'] = states.ERROR wf_ex['state'] = states.ERROR
del wf_ex.state_info del wf_ex.state_info
mock_pw.return_value = wf_ex mock_pw.return_value = wf_ex

View File

@ -57,7 +57,7 @@ WORKBOOK = {
UPDATED_WORKBOOK_DB = copy.copy(WORKBOOK_DB) UPDATED_WORKBOOK_DB = copy.copy(WORKBOOK_DB)
UPDATED_WORKBOOK_DB['definition'] = UPDATED_WORKBOOK_DEF UPDATED_WORKBOOK_DB['definition'] = UPDATED_WORKBOOK_DEF
UPDATED_WORKBOOK = copy.copy(WORKBOOK) UPDATED_WORKBOOK = copy.deepcopy(WORKBOOK)
UPDATED_WORKBOOK['definition'] = UPDATED_WORKBOOK_DEF UPDATED_WORKBOOK['definition'] = UPDATED_WORKBOOK_DEF
WB_DEF_INVALID_MODEL_EXCEPTION = """ WB_DEF_INVALID_MODEL_EXCEPTION = """

View File

@ -106,7 +106,7 @@ flow:
UPDATED_WF_DB = copy.copy(WF_DB) UPDATED_WF_DB = copy.copy(WF_DB)
UPDATED_WF_DB['definition'] = UPDATED_WF_DEFINITION UPDATED_WF_DB['definition'] = UPDATED_WF_DEFINITION
UPDATED_WF = copy.copy(WF) UPDATED_WF = copy.deepcopy(WF)
UPDATED_WF['definition'] = UPDATED_WF_DEFINITION UPDATED_WF['definition'] = UPDATED_WF_DEFINITION
WF_DEF_INVALID_MODEL_EXCEPTION = """ WF_DEF_INVALID_MODEL_EXCEPTION = """

View File

@ -885,7 +885,7 @@ class TaskExecutionTest(SQLAlchemyTest):
def test_create_and_get_and_load_task_execution(self): def test_create_and_get_and_load_task_execution(self):
wf_ex = db_api.create_workflow_execution(WF_EXECS[0]) wf_ex = db_api.create_workflow_execution(WF_EXECS[0])
values = copy.copy(TASK_EXECS[0]) values = copy.deepcopy(TASK_EXECS[0])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
created = db_api.create_task_execution(values) created = db_api.create_task_execution(values)
@ -907,7 +907,7 @@ class TaskExecutionTest(SQLAlchemyTest):
with db_api.transaction(): with db_api.transaction():
wf_ex = db_api.create_workflow_execution(WF_EXECS[0]) wf_ex = db_api.create_workflow_execution(WF_EXECS[0])
values = copy.copy(TASK_EXECS[0]) values = copy.deepcopy(TASK_EXECS[0])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
task = db_api.create_task_execution(values) task = db_api.create_task_execution(values)
@ -945,7 +945,7 @@ class TaskExecutionTest(SQLAlchemyTest):
def test_update_task_execution(self): def test_update_task_execution(self):
wf_ex = db_api.create_workflow_execution(WF_EXECS[0]) wf_ex = db_api.create_workflow_execution(WF_EXECS[0])
values = copy.copy(TASK_EXECS[0]) values = copy.deepcopy(TASK_EXECS[0])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
created = db_api.create_task_execution(values) created = db_api.create_task_execution(values)
@ -971,7 +971,7 @@ class TaskExecutionTest(SQLAlchemyTest):
wf_ex = db_api.create_workflow_execution(WF_EXECS[0]) wf_ex = db_api.create_workflow_execution(WF_EXECS[0])
values = copy.copy(TASK_EXECS[0]) values = copy.deepcopy(TASK_EXECS[0])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
created = db_api.create_or_update_task_execution(id, values) created = db_api.create_or_update_task_execution(id, values)
@ -997,12 +997,12 @@ class TaskExecutionTest(SQLAlchemyTest):
def test_get_task_executions(self): def test_get_task_executions(self):
wf_ex = db_api.create_workflow_execution(WF_EXECS[0]) wf_ex = db_api.create_workflow_execution(WF_EXECS[0])
values = copy.copy(TASK_EXECS[0]) values = copy.deepcopy(TASK_EXECS[0])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
created0 = db_api.create_task_execution(values) created0 = db_api.create_task_execution(values)
values = copy.copy(TASK_EXECS[1]) values = copy.deepcopy(TASK_EXECS[1])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
created1 = db_api.create_task_execution(values) created1 = db_api.create_task_execution(values)
@ -1018,7 +1018,7 @@ class TaskExecutionTest(SQLAlchemyTest):
def test_delete_task_execution(self): def test_delete_task_execution(self):
wf_ex = db_api.create_workflow_execution(WF_EXECS[0]) wf_ex = db_api.create_workflow_execution(WF_EXECS[0])
values = copy.copy(TASK_EXECS[0]) values = copy.deepcopy(TASK_EXECS[0])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
created = db_api.create_task_execution(values) created = db_api.create_task_execution(values)
@ -1038,7 +1038,7 @@ class TaskExecutionTest(SQLAlchemyTest):
def test_task_execution_repr(self): def test_task_execution_repr(self):
wf_ex = db_api.create_workflow_execution(WF_EXECS[0]) wf_ex = db_api.create_workflow_execution(WF_EXECS[0])
values = copy.copy(TASK_EXECS[0]) values = copy.deepcopy(TASK_EXECS[0])
values.update({'workflow_execution_id': wf_ex.id}) values.update({'workflow_execution_id': wf_ex.id})
s = db_api.create_task_execution(values).__repr__() s = db_api.create_task_execution(values).__repr__()

View File

@ -247,7 +247,7 @@ class WithItemsEngineTest(base.EngineTestCase):
def test_with_items_static_var(self): def test_with_items_static_var(self):
wb_service.create_workbook_v2(WORKBOOK_WITH_STATIC_VAR) wb_service.create_workbook_v2(WORKBOOK_WITH_STATIC_VAR)
wf_input = copy.copy(WORKFLOW_INPUT) wf_input = copy.deepcopy(WORKFLOW_INPUT)
wf_input.update({'greeting': 'Hello'}) wf_input.update({'greeting': 'Hello'})
# Start workflow. # Start workflow.
wf_ex = self.engine.start_workflow('wb1.with_items', wf_input) wf_ex = self.engine.start_workflow('wb1.with_items', wf_input)

View File

@ -98,7 +98,7 @@ class WorkflowController(object):
upstream_task_execs = self._get_upstream_task_executions(task_spec) upstream_task_execs = self._get_upstream_task_executions(task_spec)
return u.merge_dicts( return u.merge_dicts(
copy.copy(self.wf_ex.context), copy.deepcopy(self.wf_ex.context),
data_flow.evaluate_upstream_context(upstream_task_execs) data_flow.evaluate_upstream_context(upstream_task_execs)
) )