From 826ab12cbd907ccdf2ca4fb387d3bd759275638e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Sat, 23 Oct 2021 18:54:34 +0200 Subject: [PATCH 01/17] Fix issue with parameters in metadata --- qiskit/providers/ibmq/ibmqbackend.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/qiskit/providers/ibmq/ibmqbackend.py b/qiskit/providers/ibmq/ibmqbackend.py index f4f60b5b3..81dcecd0c 100644 --- a/qiskit/providers/ibmq/ibmqbackend.py +++ b/qiskit/providers/ibmq/ibmqbackend.py @@ -56,6 +56,25 @@ logger = logging.getLogger(__name__) +def _convert2json_serializable(param): + """Convert dictionary to contain only JSON serializable types. For example, + if the key is a Parameter we convert it to a string.""" + if isinstance(param, dict): + param_bind_str = {} + for key in param.keys(): + value = _convert2json_serializable(param[key]) + + if type(key) in set([str, int, float, bool]) or key is None: + param_bind_str[key] = value + else: + param_bind_str[str(key)] = value + return param_bind_str + elif isinstance(param, list): + return [_convert2json_serializable(p) for p in param] + else: + return param + + class IBMQBackend(Backend): """Backend class interfacing with an IBM Quantum Experience device. @@ -372,6 +391,9 @@ def _submit_job( """ try: qobj_dict = qobj.to_dict() + # Replace all Parameter by string + qobj_dict = _convert2json_serializable(qobj_dict) + submit_info = self._api_client.job_submit( backend_name=self.name(), qobj_dict=qobj_dict, From 779e6c5aa629a007477c4a5a972e2dfedb8e9bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Wed, 10 Nov 2021 13:12:46 +0100 Subject: [PATCH 02/17] Move encode method to json_encoder. --- qiskit/providers/ibmq/ibmqbackend.py | 22 --------------------- qiskit/providers/ibmq/utils/json_encoder.py | 22 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/qiskit/providers/ibmq/ibmqbackend.py b/qiskit/providers/ibmq/ibmqbackend.py index 81dcecd0c..f4f60b5b3 100644 --- a/qiskit/providers/ibmq/ibmqbackend.py +++ b/qiskit/providers/ibmq/ibmqbackend.py @@ -56,25 +56,6 @@ logger = logging.getLogger(__name__) -def _convert2json_serializable(param): - """Convert dictionary to contain only JSON serializable types. For example, - if the key is a Parameter we convert it to a string.""" - if isinstance(param, dict): - param_bind_str = {} - for key in param.keys(): - value = _convert2json_serializable(param[key]) - - if type(key) in set([str, int, float, bool]) or key is None: - param_bind_str[key] = value - else: - param_bind_str[str(key)] = value - return param_bind_str - elif isinstance(param, list): - return [_convert2json_serializable(p) for p in param] - else: - return param - - class IBMQBackend(Backend): """Backend class interfacing with an IBM Quantum Experience device. @@ -391,9 +372,6 @@ def _submit_job( """ try: qobj_dict = qobj.to_dict() - # Replace all Parameter by string - qobj_dict = _convert2json_serializable(qobj_dict) - submit_info = self._api_client.job_submit( backend_name=self.name(), qobj_dict=qobj_dict, diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index f8c518e62..fc82782b2 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -23,6 +23,28 @@ class IQXJsonEncoder(json.JSONEncoder): """A json encoder for qobj""" + def encode(self, o: Any) -> str: + """ + Return a JSON string representation of a Python data structure. + + Convert dictionary to contain only JSON serializable types. For example, + if the key is a Parameter we convert it to a string. + """ + if isinstance(o, dict): + param_bind_str = {} + for key in o.keys(): + value = self.encode(o[key]) + + if type(key) in set([str, int, float, bool]) or key is None: + param_bind_str[key] = value + else: + param_bind_str[str(key)] = value + return super().encode(param_bind_str) + elif isinstance(o, list): + return super().encode([self.encode(p) for p in o]) + else: + return super().encode(o) + def default(self, o: Any) -> Any: # Convert numpy arrays: if hasattr(o, 'tolist'): From 1f4856b95370d1ae80cabc5c18244e3b5cfef694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Wed, 10 Nov 2021 15:48:04 +0100 Subject: [PATCH 03/17] Fix lint issue: Using type() instead of isinstance() for a typecheck --- qiskit/providers/ibmq/utils/json_encoder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index fc82782b2..915fbb1eb 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -35,7 +35,8 @@ def encode(self, o: Any) -> str: for key in o.keys(): value = self.encode(o[key]) - if type(key) in set([str, int, float, bool]) or key is None: + if isinstance(key, str) or isinstance(key, int) or isinstance(key, float) or isinstance(key, bool)\ + or key is None: param_bind_str[key] = value else: param_bind_str[str(key)] = value From 5888566dd7e0ac05593472fbac322bc074d78015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Wed, 10 Nov 2021 16:12:23 +0100 Subject: [PATCH 04/17] Fix lint issue: E501 line too long (115 > 100 characters) --- qiskit/providers/ibmq/utils/json_encoder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index 915fbb1eb..36c52cab2 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -35,8 +35,8 @@ def encode(self, o: Any) -> str: for key in o.keys(): value = self.encode(o[key]) - if isinstance(key, str) or isinstance(key, int) or isinstance(key, float) or isinstance(key, bool)\ - or key is None: + if isinstance(key, str) or isinstance(key, int) or isinstance(key, float) \ + or isinstance(key, bool) or key is None: param_bind_str[key] = value else: param_bind_str[str(key)] = value From 0821dcac3a43d3b53e721f4f805239616c00649b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Wed, 10 Nov 2021 16:25:43 +0100 Subject: [PATCH 05/17] Fix lint issue. --- qiskit/providers/ibmq/utils/json_encoder.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index 36c52cab2..ba24f6b3e 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -35,8 +35,7 @@ def encode(self, o: Any) -> str: for key in o.keys(): value = self.encode(o[key]) - if isinstance(key, str) or isinstance(key, int) or isinstance(key, float) \ - or isinstance(key, bool) or key is None: + if isinstance(key, (bool, float, int, str)) or key is None: param_bind_str[key] = value else: param_bind_str[str(key)] = value From 7b96f00eecfd26705427a9bd78460da8f6fc171c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Wed, 10 Nov 2021 21:50:02 +0100 Subject: [PATCH 06/17] Rewrie the encode method --- qiskit/providers/ibmq/utils/json_encoder.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index ba24f6b3e..563da367f 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -23,27 +23,32 @@ class IQXJsonEncoder(json.JSONEncoder): """A json encoder for qobj""" - def encode(self, o: Any) -> str: + def __encode(self, o: Any) -> Any: """ - Return a JSON string representation of a Python data structure. - Convert dictionary to contain only JSON serializable types. For example, if the key is a Parameter we convert it to a string. """ if isinstance(o, dict): param_bind_str = {} for key in o.keys(): - value = self.encode(o[key]) + value = self.__encode(o[key]) if isinstance(key, (bool, float, int, str)) or key is None: param_bind_str[key] = value else: param_bind_str[str(key)] = value - return super().encode(param_bind_str) + return param_bind_str elif isinstance(o, list): - return super().encode([self.encode(p) for p in o]) + return [self.__encode(p) for p in o] else: - return super().encode(o) + return o + + def encode(self, o: Any) -> str: + """ + Return a JSON string representation of a Python data structure. + """ + new_o = self.__encode(o) + return super().encode(new_o) def default(self, o: Any) -> Any: # Convert numpy arrays: From 84097c42665cb628cb47ca5c92f9c244d3ddefcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Wed, 10 Nov 2021 22:04:18 +0100 Subject: [PATCH 07/17] Change the parameter name. --- qiskit/providers/ibmq/utils/json_encoder.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index 563da367f..553dd6fab 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -23,25 +23,25 @@ class IQXJsonEncoder(json.JSONEncoder): """A json encoder for qobj""" - def __encode(self, o: Any) -> Any: + def __encode(self, param: Any) -> Any: """ Convert dictionary to contain only JSON serializable types. For example, if the key is a Parameter we convert it to a string. """ - if isinstance(o, dict): + if isinstance(param, dict): param_bind_str = {} - for key in o.keys(): - value = self.__encode(o[key]) + for key in param.keys(): + value = self.__encode(param[key]) if isinstance(key, (bool, float, int, str)) or key is None: param_bind_str[key] = value else: param_bind_str[str(key)] = value return param_bind_str - elif isinstance(o, list): - return [self.__encode(p) for p in o] + elif isinstance(param, list): + return [self.__encode(p) for p in param] else: - return o + return param def encode(self, o: Any) -> str: """ From 455e400f0fb87c2760b8ebaf95a991ad3f27fa9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Thu, 11 Nov 2021 15:38:42 +0100 Subject: [PATCH 08/17] Convert to string only for Parameter. --- qiskit/providers/ibmq/utils/json_encoder.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index 553dd6fab..c6e4abd5f 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -18,6 +18,7 @@ from typing import Any from qiskit.circuit.parameterexpression import ParameterExpression +from qiskit.circuit import Parameter class IQXJsonEncoder(json.JSONEncoder): @@ -33,10 +34,10 @@ def __encode(self, param: Any) -> Any: for key in param.keys(): value = self.__encode(param[key]) - if isinstance(key, (bool, float, int, str)) or key is None: - param_bind_str[key] = value - else: + if isinstance(key, Parameter): param_bind_str[str(key)] = value + else: + param_bind_str[key] = value return param_bind_str elif isinstance(param, list): return [self.__encode(p) for p in param] From bcd33d76febc720aa26178741e92139fa8e8f6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Thu, 11 Nov 2021 16:06:00 +0100 Subject: [PATCH 09/17] Test if test pass --- qiskit/providers/ibmq/utils/json_encoder.py | 28 --------------------- 1 file changed, 28 deletions(-) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index c6e4abd5f..f8c518e62 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -18,39 +18,11 @@ from typing import Any from qiskit.circuit.parameterexpression import ParameterExpression -from qiskit.circuit import Parameter class IQXJsonEncoder(json.JSONEncoder): """A json encoder for qobj""" - def __encode(self, param: Any) -> Any: - """ - Convert dictionary to contain only JSON serializable types. For example, - if the key is a Parameter we convert it to a string. - """ - if isinstance(param, dict): - param_bind_str = {} - for key in param.keys(): - value = self.__encode(param[key]) - - if isinstance(key, Parameter): - param_bind_str[str(key)] = value - else: - param_bind_str[key] = value - return param_bind_str - elif isinstance(param, list): - return [self.__encode(p) for p in param] - else: - return param - - def encode(self, o: Any) -> str: - """ - Return a JSON string representation of a Python data structure. - """ - new_o = self.__encode(o) - return super().encode(new_o) - def default(self, o: Any) -> Any: # Convert numpy arrays: if hasattr(o, 'tolist'): From 2a89bffa4a4a145fa367f122071e4ab1174075d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Fri, 12 Nov 2021 10:12:35 +0100 Subject: [PATCH 10/17] Fix, metadata issue --- qiskit/providers/ibmq/utils/json_encoder.py | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/qiskit/providers/ibmq/utils/json_encoder.py b/qiskit/providers/ibmq/utils/json_encoder.py index f8c518e62..553dd6fab 100644 --- a/qiskit/providers/ibmq/utils/json_encoder.py +++ b/qiskit/providers/ibmq/utils/json_encoder.py @@ -23,6 +23,33 @@ class IQXJsonEncoder(json.JSONEncoder): """A json encoder for qobj""" + def __encode(self, param: Any) -> Any: + """ + Convert dictionary to contain only JSON serializable types. For example, + if the key is a Parameter we convert it to a string. + """ + if isinstance(param, dict): + param_bind_str = {} + for key in param.keys(): + value = self.__encode(param[key]) + + if isinstance(key, (bool, float, int, str)) or key is None: + param_bind_str[key] = value + else: + param_bind_str[str(key)] = value + return param_bind_str + elif isinstance(param, list): + return [self.__encode(p) for p in param] + else: + return param + + def encode(self, o: Any) -> str: + """ + Return a JSON string representation of a Python data structure. + """ + new_o = self.__encode(o) + return super().encode(new_o) + def default(self, o: Any) -> Any: # Convert numpy arrays: if hasattr(o, 'tolist'): From 081037c611598027b5c1136bff96a350e910a114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Sun, 14 Nov 2021 17:55:59 +0100 Subject: [PATCH 11/17] Add test for Parameter in metadata --- test/ibmq/utils/__init__.py | 13 ++++++++ test/ibmq/utils/test_json_encoder.py | 45 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 test/ibmq/utils/__init__.py create mode 100644 test/ibmq/utils/test_json_encoder.py diff --git a/test/ibmq/utils/__init__.py b/test/ibmq/utils/__init__.py new file mode 100644 index 000000000..3aaae807e --- /dev/null +++ b/test/ibmq/utils/__init__.py @@ -0,0 +1,13 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2017, 2018. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""Test for the qiskit-ibmq-provider package.""" diff --git a/test/ibmq/utils/test_json_encoder.py b/test/ibmq/utils/test_json_encoder.py new file mode 100644 index 000000000..7d5d795d3 --- /dev/null +++ b/test/ibmq/utils/test_json_encoder.py @@ -0,0 +1,45 @@ +from qiskit.providers.ibmq.utils.json_encoder import IQXJsonEncoder +from ...ibmqtestcase import IBMQTestCase +from ...decorators import requires_provider + +from qiskit import Aer, QuantumCircuit, QuantumRegister, ClassicalRegister +from qiskit.circuit import Parameter + + +class TestJsonEncoder(IBMQTestCase): + """Tests for AccountClient.""" + + @requires_provider + def test_exception_message(self, provider): + """Test executing job with Parameter in methadata.""" + qr = QuantumRegister(1) + cr = ClassicalRegister(1) + my_circ_str = 'test_metadata' + my_circ = QuantumCircuit(qr, cr, name=my_circ_str, metadata={Parameter('φ'): 0.2}) + backend = provider.get_backend('ibmq_bogota') + backend.run(my_circ, shots=1024) + # There is no self.assert method because if we cannot pass Parameter as metadata the last line throw: + # "TypeError: keys must be str, int, float, bool or None, not Parameter" + + def test_encode_no_replace(self): + """Test encode where there is no invalid key to replace.""" + dir = { + 't1': 1, + None: None, + 'list': [1, 2, {'ld': 1, 2: 3}] + } + + self.assertEqual('{"t1": 1, "null": null, "list": [1, 2, {"ld": 1, "2": 3}]}', IQXJsonEncoder().encode(dir)) + + def test_encode_replace(self): + """Test encode where there is no invalid key to replace.""" + dir = { + 't1': 1, + None: None, + Parameter('a'): 0.2, + 'list': [1, 2, {'ld': 1, 2: 3, Parameter('alfa'): 0.1}] + } + + self.assertEqual('{"t1": 1, "null": null, "a": 0.2, "list": [1, 2, {"ld": 1, "2": 3, "alfa": 0.1}]}', + IQXJsonEncoder().encode(dir)) + From 5c5f04865c122ecc8f58be440f3b8392dda8c385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Mon, 15 Nov 2021 09:20:23 +0100 Subject: [PATCH 12/17] Fix lint issue in test --- test/ibmq/utils/test_json_encoder.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/ibmq/utils/test_json_encoder.py b/test/ibmq/utils/test_json_encoder.py index 7d5d795d3..6fee32b1e 100644 --- a/test/ibmq/utils/test_json_encoder.py +++ b/test/ibmq/utils/test_json_encoder.py @@ -18,7 +18,8 @@ def test_exception_message(self, provider): my_circ = QuantumCircuit(qr, cr, name=my_circ_str, metadata={Parameter('φ'): 0.2}) backend = provider.get_backend('ibmq_bogota') backend.run(my_circ, shots=1024) - # There is no self.assert method because if we cannot pass Parameter as metadata the last line throw: + # There is no self.assert method because if we cannot pass Parameter as metadata + # the last line throw: # "TypeError: keys must be str, int, float, bool or None, not Parameter" def test_encode_no_replace(self): @@ -29,7 +30,8 @@ def test_encode_no_replace(self): 'list': [1, 2, {'ld': 1, 2: 3}] } - self.assertEqual('{"t1": 1, "null": null, "list": [1, 2, {"ld": 1, "2": 3}]}', IQXJsonEncoder().encode(dir)) + self.assertEqual('{"t1": 1, "null": null, "list": [1, 2, {"ld": 1, "2": 3}]}', + IQXJsonEncoder().encode(dir)) def test_encode_replace(self): """Test encode where there is no invalid key to replace.""" @@ -40,6 +42,6 @@ def test_encode_replace(self): 'list': [1, 2, {'ld': 1, 2: 3, Parameter('alfa'): 0.1}] } - self.assertEqual('{"t1": 1, "null": null, "a": 0.2, "list": [1, 2, {"ld": 1, "2": 3, "alfa": 0.1}]}', - IQXJsonEncoder().encode(dir)) - + self.assertEqual( + '{"t1": 1, "null": null, "a": 0.2, "list": [1, 2, {"ld": 1, "2": 3, "alfa": 0.1}]}', + IQXJsonEncoder().encode(dir)) From 49c2073dbf8a5215de21b21bda8fc2d17a795899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Mon, 15 Nov 2021 09:43:13 +0100 Subject: [PATCH 13/17] Fix lint issue in test --- test/ibmq/utils/__init__.py | 2 +- test/ibmq/utils/test_json_encoder.py | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/test/ibmq/utils/__init__.py b/test/ibmq/utils/__init__.py index 3aaae807e..95b709158 100644 --- a/test/ibmq/utils/__init__.py +++ b/test/ibmq/utils/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2017, 2018. +# (C) Copyright IBM 2021. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory diff --git a/test/ibmq/utils/test_json_encoder.py b/test/ibmq/utils/test_json_encoder.py index 6fee32b1e..292137c31 100644 --- a/test/ibmq/utils/test_json_encoder.py +++ b/test/ibmq/utils/test_json_encoder.py @@ -1,10 +1,24 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2021. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""Tests for the IQXJsonEncoder class.""" + from qiskit.providers.ibmq.utils.json_encoder import IQXJsonEncoder +from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister +from qiskit.circuit import Parameter + from ...ibmqtestcase import IBMQTestCase from ...decorators import requires_provider -from qiskit import Aer, QuantumCircuit, QuantumRegister, ClassicalRegister -from qiskit.circuit import Parameter - class TestJsonEncoder(IBMQTestCase): """Tests for AccountClient.""" @@ -24,18 +38,18 @@ def test_exception_message(self, provider): def test_encode_no_replace(self): """Test encode where there is no invalid key to replace.""" - dir = { + o = { 't1': 1, None: None, 'list': [1, 2, {'ld': 1, 2: 3}] } self.assertEqual('{"t1": 1, "null": null, "list": [1, 2, {"ld": 1, "2": 3}]}', - IQXJsonEncoder().encode(dir)) + IQXJsonEncoder().encode(o)) def test_encode_replace(self): """Test encode where there is no invalid key to replace.""" - dir = { + o = { 't1': 1, None: None, Parameter('a'): 0.2, @@ -44,4 +58,4 @@ def test_encode_replace(self): self.assertEqual( '{"t1": 1, "null": null, "a": 0.2, "list": [1, 2, {"ld": 1, "2": 3, "alfa": 0.1}]}', - IQXJsonEncoder().encode(dir)) + IQXJsonEncoder().encode(o)) From 3a93a75d5d40d08c5ada311dc2df9c16d7beeb7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Mon, 15 Nov 2021 11:14:50 +0100 Subject: [PATCH 14/17] Fix lint issue in test --- test/ibmq/utils/test_json_encoder.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/ibmq/utils/test_json_encoder.py b/test/ibmq/utils/test_json_encoder.py index 292137c31..fff5cace3 100644 --- a/test/ibmq/utils/test_json_encoder.py +++ b/test/ibmq/utils/test_json_encoder.py @@ -38,18 +38,18 @@ def test_exception_message(self, provider): def test_encode_no_replace(self): """Test encode where there is no invalid key to replace.""" - o = { + test_dir = { 't1': 1, None: None, 'list': [1, 2, {'ld': 1, 2: 3}] } self.assertEqual('{"t1": 1, "null": null, "list": [1, 2, {"ld": 1, "2": 3}]}', - IQXJsonEncoder().encode(o)) + IQXJsonEncoder().encode(test_dir)) def test_encode_replace(self): """Test encode where there is no invalid key to replace.""" - o = { + test_dir = { 't1': 1, None: None, Parameter('a'): 0.2, @@ -58,4 +58,4 @@ def test_encode_replace(self): self.assertEqual( '{"t1": 1, "null": null, "a": 0.2, "list": [1, 2, {"ld": 1, "2": 3, "alfa": 0.1}]}', - IQXJsonEncoder().encode(o)) + IQXJsonEncoder().encode(test_dir)) From 1d77107129e2502d3a93186286630fd5d6b082a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Tue, 16 Nov 2021 19:46:13 +0100 Subject: [PATCH 15/17] Move IQXJsonEncoder tests to test_serialization file --- test/ibmq/test_serialization.py | 42 ++++++++++++++++++- test/ibmq/utils/__init__.py | 13 ------ test/ibmq/utils/test_json_encoder.py | 61 ---------------------------- 3 files changed, 41 insertions(+), 75 deletions(-) delete mode 100644 test/ibmq/utils/__init__.py delete mode 100644 test/ibmq/utils/test_json_encoder.py diff --git a/test/ibmq/test_serialization.py b/test/ibmq/test_serialization.py index 85bd06729..89c35e2e1 100644 --- a/test/ibmq/test_serialization.py +++ b/test/ibmq/test_serialization.py @@ -19,10 +19,12 @@ from qiskit.test.reference_circuits import ReferenceCircuits from qiskit.test import slow_test from qiskit.providers.ibmq import least_busy -from qiskit import transpile, schedule, QuantumCircuit +from qiskit import transpile, schedule, assemble +from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister from qiskit.providers.ibmq.utils.json_encoder import IQXJsonEncoder from qiskit.circuit import Parameter from qiskit.version import VERSION as terra_version +import json from ..decorators import requires_provider from ..utils import cancel_job @@ -178,6 +180,44 @@ def test_convert_complex(self): self.assertEqual(val[0], 0.2) self.assertEqual(val[1], 0.1) + def test_exception_message(self): + """Test executing job with Parameter in methadata.""" + qr = QuantumRegister(1) + cr = ClassicalRegister(1) + my_circ_str = 'test_metadata' + my_circ = QuantumCircuit(qr, cr, name=my_circ_str, metadata={Parameter('φ'): 0.2}) + qobj = assemble(my_circ) + qobj_dict = qobj.to_dict() + json.dumps(qobj_dict, cls=IQXJsonEncoder) + # There is no self.assert method because if we cannot pass Parameter as metadata + # the last line throw: + # "TypeError: keys must be str, int, float, bool or None, not Parameter" + + def test_encode_no_replace(self): + """Test encode where there is no invalid key to replace.""" + test_dir = { + 't1': 1, + None: None, + 'list': [1, 2, {'ld': 1, 2: 3}] + } + + self.assertEqual('{"t1": 1, "null": null, "list": [1, 2, {"ld": 1, "2": 3}]}', + IQXJsonEncoder().encode(test_dir)) + + def test_encode_replace(self): + """Test encode where there is no invalid key to replace.""" + test_dir = { + 't1': 1, + None: None, + Parameter('a'): 0.2, + 'list': [1, 2, {'ld': 1, 2: 3, Parameter('alfa'): 0.1}] + } + + self.assertEqual( + '{"t1": 1, "null": null, "a": 0.2, "list": [1, 2, {"ld": 1, "2": 3, "alfa": 0.1}]}', + IQXJsonEncoder().encode(test_dir)) + + def _find_potential_encoded(data: Any, c_key: str, tally: set) -> None: """Find data that may be in JSON serialized format. diff --git a/test/ibmq/utils/__init__.py b/test/ibmq/utils/__init__.py deleted file mode 100644 index 95b709158..000000000 --- a/test/ibmq/utils/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2021. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Test for the qiskit-ibmq-provider package.""" diff --git a/test/ibmq/utils/test_json_encoder.py b/test/ibmq/utils/test_json_encoder.py deleted file mode 100644 index fff5cace3..000000000 --- a/test/ibmq/utils/test_json_encoder.py +++ /dev/null @@ -1,61 +0,0 @@ -# This code is part of Qiskit. -# -# (C) Copyright IBM 2021. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -"""Tests for the IQXJsonEncoder class.""" - -from qiskit.providers.ibmq.utils.json_encoder import IQXJsonEncoder -from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister -from qiskit.circuit import Parameter - -from ...ibmqtestcase import IBMQTestCase -from ...decorators import requires_provider - - -class TestJsonEncoder(IBMQTestCase): - """Tests for AccountClient.""" - - @requires_provider - def test_exception_message(self, provider): - """Test executing job with Parameter in methadata.""" - qr = QuantumRegister(1) - cr = ClassicalRegister(1) - my_circ_str = 'test_metadata' - my_circ = QuantumCircuit(qr, cr, name=my_circ_str, metadata={Parameter('φ'): 0.2}) - backend = provider.get_backend('ibmq_bogota') - backend.run(my_circ, shots=1024) - # There is no self.assert method because if we cannot pass Parameter as metadata - # the last line throw: - # "TypeError: keys must be str, int, float, bool or None, not Parameter" - - def test_encode_no_replace(self): - """Test encode where there is no invalid key to replace.""" - test_dir = { - 't1': 1, - None: None, - 'list': [1, 2, {'ld': 1, 2: 3}] - } - - self.assertEqual('{"t1": 1, "null": null, "list": [1, 2, {"ld": 1, "2": 3}]}', - IQXJsonEncoder().encode(test_dir)) - - def test_encode_replace(self): - """Test encode where there is no invalid key to replace.""" - test_dir = { - 't1': 1, - None: None, - Parameter('a'): 0.2, - 'list': [1, 2, {'ld': 1, 2: 3, Parameter('alfa'): 0.1}] - } - - self.assertEqual( - '{"t1": 1, "null": null, "a": 0.2, "list": [1, 2, {"ld": 1, "2": 3, "alfa": 0.1}]}', - IQXJsonEncoder().encode(test_dir)) From aaf88671a18c6f2f1e4deba470dca1bb5bd81196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Tue, 16 Nov 2021 19:49:28 +0100 Subject: [PATCH 16/17] Fix lint issue in test --- test/ibmq/test_serialization.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/ibmq/test_serialization.py b/test/ibmq/test_serialization.py index 89c35e2e1..55feeea7f 100644 --- a/test/ibmq/test_serialization.py +++ b/test/ibmq/test_serialization.py @@ -218,7 +218,6 @@ def test_encode_replace(self): IQXJsonEncoder().encode(test_dir)) - def _find_potential_encoded(data: Any, c_key: str, tally: set) -> None: """Find data that may be in JSON serialized format. From 76063d01273320b9de310559c07b4babae40e788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Pracht?= Date: Tue, 16 Nov 2021 20:02:09 +0100 Subject: [PATCH 17/17] Fix lint issue in test --- test/ibmq/test_serialization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ibmq/test_serialization.py b/test/ibmq/test_serialization.py index 55feeea7f..e88d2dcb2 100644 --- a/test/ibmq/test_serialization.py +++ b/test/ibmq/test_serialization.py @@ -15,6 +15,7 @@ from unittest import SkipTest, skipIf from typing import Any, Dict, Optional +import json import dateutil.parser from qiskit.test.reference_circuits import ReferenceCircuits from qiskit.test import slow_test @@ -24,7 +25,6 @@ from qiskit.providers.ibmq.utils.json_encoder import IQXJsonEncoder from qiskit.circuit import Parameter from qiskit.version import VERSION as terra_version -import json from ..decorators import requires_provider from ..utils import cancel_job