diff --git a/mistralclient/api/base.py b/mistralclient/api/base.py index 5bda3188..f15244b9 100644 --- a/mistralclient/api/base.py +++ b/mistralclient/api/base.py @@ -13,9 +13,10 @@ # limitations under the License. import copy -import json import six +from oslo_serialization import jsonutils + from keystoneauth1 import exceptions urlparse = six.moves.urllib.parse @@ -134,7 +135,7 @@ class ResourceManager(object): def _create(self, url, data, response_key=None, dump_json=True): if dump_json: - data = json.dumps(data) + data = jsonutils.dumps(data) try: resp = self.http_client.post(url, data) @@ -148,7 +149,7 @@ class ResourceManager(object): def _update(self, url, data, response_key=None, dump_json=True): if dump_json: - data = json.dumps(data) + data = jsonutils.dumps(data) try: resp = self.http_client.put(url, data) @@ -216,7 +217,7 @@ def get_json(response): if callable(json_field_or_function): return response.json() else: - return json.loads(response.content) + return jsonutils.loads(response.content) class APIException(Exception): diff --git a/mistralclient/api/v2/action_executions.py b/mistralclient/api/v2/action_executions.py index 628bdc13..ef98261f 100644 --- a/mistralclient/api/v2/action_executions.py +++ b/mistralclient/api/v2/action_executions.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json +from oslo_serialization import jsonutils from mistralclient.api import base @@ -30,10 +30,10 @@ class ActionExecutionManager(base.ResourceManager): data = {'name': name} if input: - data['input'] = json.dumps(input) + data['input'] = jsonutils.dumps(input) if params: - data['params'] = json.dumps(params) + data['params'] = jsonutils.dumps(params) return self._create( '/action_executions', diff --git a/mistralclient/api/v2/cron_triggers.py b/mistralclient/api/v2/cron_triggers.py index 13e8e135..71672072 100644 --- a/mistralclient/api/v2/cron_triggers.py +++ b/mistralclient/api/v2/cron_triggers.py @@ -12,8 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json - +from oslo_serialization import jsonutils from oslo_utils import uuidutils from mistralclient.api import base @@ -47,10 +46,10 @@ class CronTriggerManager(base.ResourceManager): data.update({'workflow_name': workflow_identifier}) if workflow_input: - data.update({'workflow_input': json.dumps(workflow_input)}) + data.update({'workflow_input': jsonutils.dumps(workflow_input)}) if workflow_params: - data.update({'workflow_params': json.dumps(workflow_params)}) + data.update({'workflow_params': jsonutils.dumps(workflow_params)}) return self._create('/cron_triggers', data) diff --git a/mistralclient/api/v2/environments.py b/mistralclient/api/v2/environments.py index 8e7a756f..5b6a493e 100644 --- a/mistralclient/api/v2/environments.py +++ b/mistralclient/api/v2/environments.py @@ -12,9 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json import six +from oslo_serialization import jsonutils + from mistralclient.api import base from mistralclient import utils @@ -26,7 +27,7 @@ class Environment(base.Resource): """Override loading of the "variables" attribute from text to dict.""" for k, v in self._data.items(): if k == 'variables' and isinstance(v, six.string_types): - v = json.loads(v) + v = jsonutils.loads(v) try: setattr(self, k, v) @@ -50,7 +51,7 @@ class EnvironmentManager(base.ResourceManager): # Convert dict to text for the variables attribute. if isinstance(kwargs['variables'], dict): - kwargs['variables'] = json.dumps(kwargs['variables']) + kwargs['variables'] = jsonutils.dumps(kwargs['variables']) return self._create('/environments', kwargs) @@ -66,7 +67,7 @@ class EnvironmentManager(base.ResourceManager): # Convert dict to text for the variables attribute. if kwargs.get('variables') and isinstance(kwargs['variables'], dict): - kwargs['variables'] = json.dumps(kwargs['variables']) + kwargs['variables'] = jsonutils.dumps(kwargs['variables']) return self._update('/environments', kwargs) diff --git a/mistralclient/api/v2/event_triggers.py b/mistralclient/api/v2/event_triggers.py index e20df26c..f2880448 100644 --- a/mistralclient/api/v2/event_triggers.py +++ b/mistralclient/api/v2/event_triggers.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json +from oslo_serialization import jsonutils from mistralclient.api import base @@ -40,10 +40,10 @@ class EventTriggerManager(base.ResourceManager): } if workflow_input: - data.update({'workflow_input': json.dumps(workflow_input)}) + data.update({'workflow_input': jsonutils.dumps(workflow_input)}) if workflow_params: - data.update({'workflow_params': json.dumps(workflow_params)}) + data.update({'workflow_params': jsonutils.dumps(workflow_params)}) return self._create('/event_triggers', data) diff --git a/mistralclient/api/v2/executions.py b/mistralclient/api/v2/executions.py index b62e1b25..c65bd62c 100644 --- a/mistralclient/api/v2/executions.py +++ b/mistralclient/api/v2/executions.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json import six +from oslo_serialization import jsonutils from oslo_utils import uuidutils from mistralclient.api import base @@ -53,10 +53,10 @@ class ExecutionManager(base.ResourceManager): if isinstance(workflow_input, six.string_types): data.update({'input': workflow_input}) else: - data.update({'input': json.dumps(workflow_input)}) + data.update({'input': jsonutils.dumps(workflow_input)}) if params: - data.update({'params': json.dumps(params)}) + data.update({'params': jsonutils.dumps(params)}) return self._create('/executions', data) diff --git a/mistralclient/api/v2/tasks.py b/mistralclient/api/v2/tasks.py index ae590ce0..780eb8c4 100644 --- a/mistralclient/api/v2/tasks.py +++ b/mistralclient/api/v2/tasks.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json +from oslo_serialization import jsonutils from mistralclient.api import base @@ -60,6 +60,6 @@ class TaskManager(base.ResourceManager): } if env: - body['env'] = json.dumps(env) + body['env'] = jsonutils.dumps(env) return self._update(url, body) diff --git a/mistralclient/commands/v2/action_executions.py b/mistralclient/commands/v2/action_executions.py index 8ae9ba02..e4be423c 100644 --- a/mistralclient/commands/v2/action_executions.py +++ b/mistralclient/commands/v2/action_executions.py @@ -14,9 +14,10 @@ # under the License. # -import json import logging +from oslo_serialization import jsonutils + from osc_lib.command import command from mistralclient.commands.v2 import base @@ -259,8 +260,8 @@ class GetOutput(command.Command): output = mistral_client.action_executions.get(parsed_args.id).output try: - output = json.loads(output) - output = json.dumps(output, indent=4) + "\n" + output = jsonutils.loads(output) + output = jsonutils.dumps(output, indent=4) + "\n" except Exception: LOG.debug("Task result is not JSON.") @@ -284,8 +285,8 @@ class GetInput(command.Command): result = mistral_client.action_executions.get(parsed_args.id).input try: - result = json.loads(result) - result = json.dumps(result, indent=4) + "\n" + result = jsonutils.loads(result) + result = jsonutils.dumps(result, indent=4) + "\n" except Exception: LOG.debug("Task result is not JSON.") diff --git a/mistralclient/commands/v2/environments.py b/mistralclient/commands/v2/environments.py index 8ae8039e..9c1bbeb9 100644 --- a/mistralclient/commands/v2/environments.py +++ b/mistralclient/commands/v2/environments.py @@ -13,7 +13,8 @@ # limitations under the License. import argparse -import json + +from oslo_serialization import jsonutils from osc_lib.command import command @@ -48,7 +49,7 @@ class EnvironmentFormatter(base.MistralFormatter): else: data += (None,) if not lister: - data += (json.dumps(environment.variables, indent=4),) + data += (jsonutils.dumps(environment.variables, indent=4),) data += ( environment.scope, environment.created_at,) @@ -113,7 +114,7 @@ class Get(command.ShowOne): data = (environment.name, environment.description, environment.scope, - json.dumps(environment.variables)) + jsonutils.dumps(environment.variables)) return columns, data diff --git a/mistralclient/commands/v2/executions.py b/mistralclient/commands/v2/executions.py index 4af5105e..74cc551c 100644 --- a/mistralclient/commands/v2/executions.py +++ b/mistralclient/commands/v2/executions.py @@ -17,10 +17,11 @@ # under the License. # -import json import logging import os.path +from oslo_serialization import jsonutils + from osc_lib.command import command from mistralclient.commands.v2 import base @@ -296,8 +297,8 @@ class GetInput(command.Command): ex_input = mistral_client.executions.get(parsed_args.id).input try: - ex_input = json.loads(ex_input) - ex_input = json.dumps(ex_input, indent=4) + "\n" + ex_input = jsonutils.loads(ex_input) + ex_input = jsonutils.dumps(ex_input, indent=4) + "\n" except Exception: LOG.debug("Execution input is not JSON.") @@ -320,8 +321,8 @@ class GetOutput(command.Command): output = mistral_client.executions.get(parsed_args.id).output try: - output = json.loads(output) - output = json.dumps(output, indent=4) + "\n" + output = jsonutils.loads(output) + output = jsonutils.dumps(output, indent=4) + "\n" except Exception: LOG.debug("Execution output is not JSON.") diff --git a/mistralclient/commands/v2/tasks.py b/mistralclient/commands/v2/tasks.py index e7f608e5..0951b388 100644 --- a/mistralclient/commands/v2/tasks.py +++ b/mistralclient/commands/v2/tasks.py @@ -15,10 +15,11 @@ # under the License. # -import json import logging import os.path +from oslo_serialization import jsonutils + from osc_lib.command import command from mistralclient.commands.v2 import base @@ -126,8 +127,8 @@ class GetResult(command.Command): result = mistral_client.tasks.get(parsed_args.id).result try: - result = json.loads(result) - result = json.dumps(result, indent=4) + "\n" + result = jsonutils.loads(result) + result = jsonutils.dumps(result, indent=4) + "\n" except Exception: LOG.debug("Task result is not JSON.") @@ -150,8 +151,8 @@ class GetPublished(command.Command): result = mistral_client.tasks.get(parsed_args.id).published try: - result = json.loads(result) - result = json.dumps(result, indent=4) + "\n" + result = jsonutils.loads(result) + result = jsonutils.dumps(result, indent=4) + "\n" except Exception: LOG.debug("Task result is not JSON.") diff --git a/mistralclient/tests/unit/test_client.py b/mistralclient/tests/unit/test_client.py index 8bb5903b..473f868a 100644 --- a/mistralclient/tests/unit/test_client.py +++ b/mistralclient/tests/unit/test_client.py @@ -13,11 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json import os import tempfile import mock +from oslo_serialization import jsonutils from oslo_utils import uuidutils from oslotest import base import osprofiler.profiler @@ -40,7 +40,7 @@ class BaseClientTests(base.BaseTestCase): keystone_client_instance.auth_token = uuidutils.generate_uuid() keystone_client_instance.project_id = uuidutils.generate_uuid() keystone_client_instance.user_id = uuidutils.generate_uuid() - keystone_client_instance.auth_ref = str(json.dumps({})) + keystone_client_instance.auth_ref = str(jsonutils.dumps({})) return keystone_client_instance @mock.patch('keystoneauth1.session.Session') diff --git a/mistralclient/tests/unit/test_utils.py b/mistralclient/tests/unit/test_utils.py index 51343d6d..83f4bcd2 100644 --- a/mistralclient/tests/unit/test_utils.py +++ b/mistralclient/tests/unit/test_utils.py @@ -12,17 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json import os.path import tempfile import yaml from mistralclient import utils +from oslo_serialization import jsonutils from oslotest import base ENV_DICT = {'k1': 'abc', 'k2': 123, 'k3': True} -ENV_STR = json.dumps(ENV_DICT) +ENV_STR = jsonutils.dumps(ENV_DICT) ENV_YAML = yaml.safe_dump(ENV_DICT, default_flow_style=False) diff --git a/mistralclient/tests/unit/v2/test_cli_action_execs.py b/mistralclient/tests/unit/v2/test_cli_action_execs.py index 786026c0..691aee74 100644 --- a/mistralclient/tests/unit/v2/test_cli_action_execs.py +++ b/mistralclient/tests/unit/v2/test_cli_action_execs.py @@ -15,13 +15,14 @@ # import copy -import json import sys import six import mock +from oslo_serialization import jsonutils + from mistralclient.api.v2 import action_executions as action_ex from mistralclient.commands.v2 import action_executions as action_ex_cmd from mistralclient.tests.unit import base @@ -44,10 +45,11 @@ ACTION_EX_RESULT = {"test": "is", "passed": "successfully"} ACTION_EX_INPUT = {"param1": "val1", "param2": 2} ACTION_EX_WITH_OUTPUT_DICT = ACTION_EX_DICT.copy() -ACTION_EX_WITH_OUTPUT_DICT.update({'output': json.dumps(ACTION_EX_RESULT)}) +ACTION_EX_WITH_OUTPUT_DICT.update( + {'output': jsonutils.dumps(ACTION_EX_RESULT)}) ACTION_EX_WITH_INPUT_DICT = ACTION_EX_DICT.copy() -ACTION_EX_WITH_INPUT_DICT.update({'input': json.dumps(ACTION_EX_INPUT)}) +ACTION_EX_WITH_INPUT_DICT.update({'input': jsonutils.dumps(ACTION_EX_INPUT)}) ACTION_EX = action_ex.ActionExecution(mock, ACTION_EX_DICT) ACTION_EX_WITH_OUTPUT = action_ex.ActionExecution( @@ -72,7 +74,7 @@ class TestCLIActionExecutions(base.BaseCommandTest): self.assertDictEqual( ACTION_EX_RESULT, - json.loads(self.app.stdout.write.call_args[0][0]) + jsonutils.loads(self.app.stdout.write.call_args[0][0]) ) def test_create_save_result(self): @@ -105,7 +107,7 @@ class TestCLIActionExecutions(base.BaseCommandTest): self.assertDictEqual( ACTION_EX_RESULT, - json.loads(self.app.stdout.write.call_args[0][0]) + jsonutils.loads(self.app.stdout.write.call_args[0][0]) ) def test_create_run_sync_and_save_result(self): @@ -121,7 +123,7 @@ class TestCLIActionExecutions(base.BaseCommandTest): self.assertDictEqual( ACTION_EX_RESULT, - json.loads(self.app.stdout.write.call_args[0][0]) + jsonutils.loads(self.app.stdout.write.call_args[0][0]) ) def test_update(self): @@ -202,7 +204,7 @@ class TestCLIActionExecutions(base.BaseCommandTest): self.assertDictEqual( ACTION_EX_RESULT, - json.loads(self.app.stdout.write.call_args[0][0]) + jsonutils.loads(self.app.stdout.write.call_args[0][0]) ) def test_get_input(self): @@ -212,7 +214,7 @@ class TestCLIActionExecutions(base.BaseCommandTest): self.assertDictEqual( ACTION_EX_INPUT, - json.loads(self.app.stdout.write.call_args[0][0]) + jsonutils.loads(self.app.stdout.write.call_args[0][0]) ) def test_delete(self): diff --git a/mistralclient/tests/unit/v2/test_cli_environments.py b/mistralclient/tests/unit/v2/test_cli_environments.py index 539a075e..8188a03e 100644 --- a/mistralclient/tests/unit/v2/test_cli_environments.py +++ b/mistralclient/tests/unit/v2/test_cli_environments.py @@ -14,10 +14,11 @@ import copy import datetime -import json import os import tempfile +from oslo_serialization import jsonutils + import mock import yaml @@ -43,7 +44,7 @@ ENVIRONMENT_DICT = { ENVIRONMENT = environments.Environment(mock, ENVIRONMENT_DICT) EXPECTED_RESULT = (ENVIRONMENT_DICT['name'], ENVIRONMENT_DICT['description'], - json.dumps(ENVIRONMENT_DICT['variables'], indent=4), + jsonutils.dumps(ENVIRONMENT_DICT['variables'], indent=4), ENVIRONMENT_DICT['scope'], ENVIRONMENT_DICT['created_at'], ENVIRONMENT_DICT['updated_at']) @@ -51,7 +52,7 @@ EXPECTED_RESULT = (ENVIRONMENT_DICT['name'], EXPECTED_EXPORT_RESULT = (ENVIRONMENT_DICT['name'], ENVIRONMENT_DICT['description'], ENVIRONMENT_DICT['scope'], - json.dumps(ENVIRONMENT_DICT['variables'])) + jsonutils.dumps(ENVIRONMENT_DICT['variables'])) class TestCLIEnvironmentsV2(base.BaseCommandTest): @@ -67,7 +68,7 @@ class TestCLIEnvironmentsV2(base.BaseCommandTest): self.assertEqual(EXPECTED_RESULT, result[1]) def test_create_from_json(self): - self._test_create(json.dumps(ENVIRONMENT_DICT, indent=4)) + self._test_create(jsonutils.dumps(ENVIRONMENT_DICT, indent=4)) def test_create_from_yaml(self): yml = yaml.dump(ENVIRONMENT_DICT, default_flow_style=False) @@ -87,7 +88,7 @@ class TestCLIEnvironmentsV2(base.BaseCommandTest): env = copy.deepcopy(ENVIRONMENT_DICT) del env['created_at'] del env['updated_at'] - self._test_update(json.dumps(env, indent=4)) + self._test_update(jsonutils.dumps(env, indent=4)) def test_update_from_yaml(self): env = copy.deepcopy(ENVIRONMENT_DICT) diff --git a/mistralclient/tests/unit/v2/test_cli_tasks.py b/mistralclient/tests/unit/v2/test_cli_tasks.py index 08cdda1a..9075f72b 100644 --- a/mistralclient/tests/unit/v2/test_cli_tasks.py +++ b/mistralclient/tests/unit/v2/test_cli_tasks.py @@ -15,7 +15,7 @@ # under the License. # -import json +from oslo_serialization import jsonutils import mock @@ -39,9 +39,9 @@ TASK_RESULT = {"test": "is", "passed": "successfully"} TASK_PUBLISHED = {"bar1": "val1", "var2": 2} TASK_WITH_RESULT_DICT = TASK_DICT.copy() -TASK_WITH_RESULT_DICT.update({'result': json.dumps(TASK_RESULT)}) +TASK_WITH_RESULT_DICT.update({'result': jsonutils.dumps(TASK_RESULT)}) TASK_WITH_PUBLISHED_DICT = TASK_DICT.copy() -TASK_WITH_PUBLISHED_DICT.update({'published': json.dumps(TASK_PUBLISHED)}) +TASK_WITH_PUBLISHED_DICT.update({'published': jsonutils.dumps(TASK_PUBLISHED)}) TASK = tasks.Task(mock, TASK_DICT) TASK_WITH_RESULT = tasks.Task(mock, TASK_WITH_RESULT_DICT) @@ -85,7 +85,7 @@ class TestCLITasksV2(base.BaseCommandTest): self.assertDictEqual( TASK_RESULT, - json.loads(self.app.stdout.write.call_args[0][0]) + jsonutils.loads(self.app.stdout.write.call_args[0][0]) ) def test_get_published(self): @@ -95,7 +95,7 @@ class TestCLITasksV2(base.BaseCommandTest): self.assertDictEqual( TASK_PUBLISHED, - json.loads(self.app.stdout.write.call_args[0][0]) + jsonutils.loads(self.app.stdout.write.call_args[0][0]) ) def test_rerun(self): diff --git a/mistralclient/tests/unit/v2/test_environments.py b/mistralclient/tests/unit/v2/test_environments.py index b087e7b0..81e25fae 100644 --- a/mistralclient/tests/unit/v2/test_environments.py +++ b/mistralclient/tests/unit/v2/test_environments.py @@ -11,11 +11,13 @@ # WITHOUT 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 collections import copy -import json import os.path +from oslo_serialization import jsonutils + import pkg_resources as pkg from six.moves.urllib import parse from six.moves.urllib import request @@ -52,7 +54,8 @@ class TestEnvironmentsV2(base.BaseClientV2Test): self.assertIsNotNone(env) expected_data = copy.deepcopy(data) - expected_data['variables'] = json.dumps(expected_data['variables']) + expected_data['variables'] = jsonutils.dumps( + expected_data['variables']) self.assertEqual(expected_data, self.requests_mock.last_request.json()) @@ -81,7 +84,8 @@ class TestEnvironmentsV2(base.BaseClientV2Test): self.assertIsNotNone(env) expected_data = copy.deepcopy(data) - expected_data['variables'] = json.dumps(expected_data['variables']) + expected_data['variables'] = jsonutils.dumps( + expected_data['variables']) self.assertEqual(expected_data, self.requests_mock.last_request.json()) @@ -104,7 +108,8 @@ class TestEnvironmentsV2(base.BaseClientV2Test): self.assertIsNotNone(env) expected_data = copy.deepcopy(data) - expected_data['variables'] = json.dumps(expected_data['variables']) + expected_data['variables'] = jsonutils.dumps( + expected_data['variables']) self.assertEqual(expected_data, self.requests_mock.last_request.json()) @@ -127,7 +132,8 @@ class TestEnvironmentsV2(base.BaseClientV2Test): self.assertIsNotNone(env) expected_data = copy.deepcopy(data) - expected_data['variables'] = json.dumps(expected_data['variables']) + expected_data['variables'] = jsonutils.dumps( + expected_data['variables']) self.assertEqual(expected_data, self.requests_mock.last_request.json()) diff --git a/mistralclient/tests/unit/v2/test_executions.py b/mistralclient/tests/unit/v2/test_executions.py index 2c7c3417..9725939c 100644 --- a/mistralclient/tests/unit/v2/test_executions.py +++ b/mistralclient/tests/unit/v2/test_executions.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json +from oslo_serialization import jsonutils from mistralclient.api import base as api_base from mistralclient.api.v2 import executions @@ -67,7 +67,7 @@ class TestExecutionsV2(base.BaseClientV2Test): body = { 'workflow_name': EXEC['workflow_name'], 'description': '', - 'input': json.dumps(EXEC['input']) + 'input': jsonutils.dumps(EXEC['input']) } ex = self.executions.create( @@ -93,7 +93,7 @@ class TestExecutionsV2(base.BaseClientV2Test): body = { 'workflow_id': EXEC['workflow_id'], 'description': '', - 'input': json.dumps(EXEC['input']) + 'input': jsonutils.dumps(EXEC['input']) } ex = self.executions.create( diff --git a/mistralclient/tests/unit/v2/test_tasks.py b/mistralclient/tests/unit/v2/test_tasks.py index 82ceb980..92299e5e 100644 --- a/mistralclient/tests/unit/v2/test_tasks.py +++ b/mistralclient/tests/unit/v2/test_tasks.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json +from oslo_serialization import jsonutils from mistralclient.api.v2 import tasks from mistralclient.tests.unit.v2 import base @@ -133,6 +133,6 @@ class TestTasksV2(base.BaseClientV2Test): 'reset': True, 'state': 'RUNNING', 'id': TASK['id'], - 'env': json.dumps({'k1': 'foobar'}) + 'env': jsonutils.dumps({'k1': 'foobar'}) } self.assertDictEqual(body, self.requests_mock.last_request.json()) diff --git a/mistralclient/utils.py b/mistralclient/utils.py index 4459765e..4653ef3b 100644 --- a/mistralclient/utils.py +++ b/mistralclient/utils.py @@ -13,10 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -import json import os import yaml +from oslo_serialization import jsonutils + from six.moves.urllib import parse from six.moves.urllib import request @@ -46,7 +47,7 @@ def load_content(content): try: data = yaml.safe_load(content) except Exception: - data = json.loads(content) + data = jsonutils.loads(content) return data @@ -83,7 +84,8 @@ def get_contents_if_file(contents_or_file_name): def load_json(input_string): try: - with open(input_string) as fh: - return json.load(fh) + # binary mode is needed due to bug/1515231 + with open(input_string, 'r+b') as fh: + return jsonutils.load(fh) except IOError: - return json.loads(input_string) + return jsonutils.loads(input_string)