diff --git a/beat/backend/python/algorithm.py b/beat/backend/python/algorithm.py index a3d77ec68636fb62791f295fe51a5717f99a75f6..2cb4a95edc06315c0f318458d883a4ccdfa2be47 100644 --- a/beat/backend/python/algorithm.py +++ b/beat/backend/python/algorithm.py @@ -48,7 +48,7 @@ import logging import six import numpy -import simplejson +import simplejson as json from . import dataformat from . import library @@ -433,7 +433,14 @@ class Algorithm(object): return with open(json_path, "rb") as f: - self.data = simplejson.loads(f.read().decode("utf-8")) + try: + self.data = json.loads( + f.read().decode("utf-8"), + object_pairs_hook=utils.error_on_duplicate_key_hook, + ) + except RuntimeError as error: + self.errors.append("Algorithm declaration file invalid: %s" % error) + return self.code_path = self.storage.code.path self.code = self.storage.code.load() @@ -938,7 +945,7 @@ class Algorithm(object): """ - return simplejson.dumps(self.data, indent=indent, cls=utils.NumpyJSONEncoder) + return json.dumps(self.data, indent=indent, cls=utils.NumpyJSONEncoder) def __str__(self): return self.json_dumps() diff --git a/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.json b/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.json new file mode 100644 index 0000000000000000000000000000000000000000..a0bc8a4a9b570070660fcbbd55767842db731578 --- /dev/null +++ b/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.json @@ -0,0 +1,19 @@ +{ + "language": "python", + "splittable": false, + "splittable": true, + "groups": [ + { + "inputs": { + "in": { + "type": "user/single_integer/1" + } + }, + "outputs": { + "out": { + "type": "user/single_integer/1" + } + } + } + ] +} diff --git a/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.py b/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.py new file mode 100644 index 0000000000000000000000000000000000000000..164f5ad741e0db32021d2f210243cf9871ba449b --- /dev/null +++ b/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# vim: set fileencoding=utf-8 : + +################################################################################### +# # +# Copyright (c) 2019 Idiap Research Institute, http://www.idiap.ch/ # +# Contact: beat.support@idiap.ch # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, this # +# list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright notice, # +# this list of conditions and the following disclaimer in the documentation # +# and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its contributors # +# may be used to endorse or promote products derived from this software without # +# specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +# # +################################################################################### + + +class Algorithm: + def process(self, inputs, outputs): + return True diff --git a/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.rst b/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.rst new file mode 100644 index 0000000000000000000000000000000000000000..e62c1c42520de03eed49b89f3ed95fce122745de --- /dev/null +++ b/beat/backend/python/test/prefix/algorithms/legacy/duplicate_key_error/1.rst @@ -0,0 +1 @@ +Test documentation diff --git a/beat/backend/python/test/test_algorithm.py b/beat/backend/python/test/test_algorithm.py index 4c1ce40577c38cab0edc4f4f8580a30d516571ea..0e75b54f478e66c2af71d0e9466254f1898586bb 100644 --- a/beat/backend/python/test/test_algorithm.py +++ b/beat/backend/python/test/test_algorithm.py @@ -92,6 +92,13 @@ class TestLegacyAPI_Loading(unittest.TestCase): with self.assertRaises(AttributeError): algorithm.runner() + def test_duplicate_key_error(self): + algorithm = Algorithm(prefix, "legacy/duplicate_key_error/1") + self.assertFalse(algorithm.valid) + self.assertNotEqual( + algorithm.errors[0].find("Algorithm declaration file invalid"), -1 + ) + def test_load_valid_algorithm(self): algorithm = Algorithm(prefix, "legacy/valid_algorithm/1") self.assertEqual(algorithm.name, "legacy/valid_algorithm/1")