diff --git a/qiskit_ibm_provider/utils/json.py b/qiskit_ibm_provider/utils/json.py index 7853e1550..380d9b000 100644 --- a/qiskit_ibm_provider/utils/json.py +++ b/qiskit_ibm_provider/utils/json.py @@ -203,8 +203,9 @@ def default(self, obj: Any) -> Any: # pylint: disable=arguments-differ return {"__type__": "ndarray", "__value__": obj.tolist()} value = _serialize_and_encode(obj, np.save, allow_pickle=False) return {"__type__": "ndarray", "__value__": value} - if isinstance(obj, np.int64): - return {"__type__": "int", "__value__": int(obj)} + if isinstance(obj, np.number): + # Maybe we should encode the numpy data type here for better accuracy. + return {"__type__": type(obj.item()).__name__, "__value__": obj.item()} if isinstance(obj, set): return {"__type__": "set", "__value__": list(obj)} if isinstance(obj, Result): @@ -294,7 +295,14 @@ def object_hook(self, obj: Any) -> Any: if obj_type == "set": return set(obj_val) if obj_type == "QuantumCircuit": - return _decode_and_deserialize(obj_val, load)[0] + return _decode_and_deserialize( + data=obj_val, + deserializer=lambda buff: load( + buff, metadata_deserializer=RuntimeDecoder + ), + )[ + 0 + ] # type: ignore[no-untyped-call] if obj_type == "Parameter": return _decode_and_deserialize(obj_val, _read_parameter, False) if obj_type == "ParameterExpression": diff --git a/releasenotes/notes/bug-fix-metadata-numpy-number-support-7613af6c44b99107.yaml b/releasenotes/notes/bug-fix-metadata-numpy-number-support-7613af6c44b99107.yaml new file mode 100644 index 000000000..25f711b55 --- /dev/null +++ b/releasenotes/notes/bug-fix-metadata-numpy-number-support-7613af6c44b99107.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed an issue where circuit metadata was not being serialized correctly + for numpy numbers. In addition, added `RuntimeDecoder` as metadata deserializer. diff --git a/test/unit/test_serialization.py b/test/unit/test_serialization.py index d3b5cefc7..b1700a484 100644 --- a/test/unit/test_serialization.py +++ b/test/unit/test_serialization.py @@ -14,6 +14,9 @@ import json import numpy as np + +from ddt import data, ddt + from qiskit import assemble from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister from qiskit.circuit import Parameter @@ -23,6 +26,7 @@ from ..ibm_test_case import IBMTestCase +@ddt class TestSerialization(IBMTestCase): """Test data serialization.""" @@ -67,11 +71,20 @@ def test_encode_replace(self): IBMJsonEncoder().encode(test_dir), ) - def test_circuit_metadata(self): + @data( + np.arange(0, 10, 1), + np.arange(0.0, 10.0, 1), + np.int32(1), + np.int64(2), + np.float64(3.1), + complex(1, 1), + np.complex64(complex(1, 3)), + "TEST", + ) + def test_circuit_metadata(self, metadata_test): """Test serializing circuit metadata.""" - circ = QuantumCircuit(1) - circ.metadata = {"test": np.arange(0, 10)} + circ.metadata = {"test": metadata_test} payload = {"circuits": [circ]} self.assertTrue(json.dumps(payload, cls=RuntimeEncoder))