Source code for qcodes.utils.json_utils

import collections
import json
import numbers
from typing import Any

import numpy as np


[docs]class NumpyJSONEncoder(json.JSONEncoder): """ This JSON encoder adds support for serializing types that the built-in ``json`` module does not support out-of-the-box. See the docstring of the ``default`` method for the description of all conversions. """
[docs] def default(self, obj: Any) -> Any: """ List of conversions that this encoder performs: * ``numpy.generic`` (all integer, floating, and other types) gets converted to its python equivalent using its ``item`` method (see ``numpy`` docs for more information, https://docs.scipy.org/doc/numpy/reference/arrays.scalars.html). * ``numpy.ndarray`` gets converted to python list using its ``tolist`` method. * Complex number (a number that conforms to ``numbers.Complex`` ABC) gets converted to a dictionary with fields ``re`` and ``im`` containing floating numbers for the real and imaginary parts respectively, and a field ``__dtype__`` containing value ``complex``. * Numbers with uncertainties (numbers that conforms to ``uncertainties.UFloat``) get converted to a dictionary with fields ``nominal_value`` and ``std_dev`` containing floating numbers for the nominal and uncertainty parts respectively, and a field ``__dtype__`` containing value ``UFloat``. * Object with a ``_JSONEncoder`` method get converted the return value of that method. * Objects which support the pickle protocol get converted using the data provided by that protocol. * Other objects which cannot be serialized get converted to their string representation (using the ``str`` function). """ import uncertainties if isinstance(obj, np.generic) and not isinstance(obj, np.complexfloating): # for numpy scalars return obj.item() elif isinstance(obj, np.ndarray): # for numpy arrays return obj.tolist() elif isinstance(obj, numbers.Complex) and not isinstance(obj, numbers.Real): return { "__dtype__": "complex", "re": float(obj.real), "im": float(obj.imag), } elif isinstance(obj, uncertainties.UFloat): return { "__dtype__": "UFloat", "nominal_value": float(obj.nominal_value), "std_dev": float(obj.std_dev), } elif hasattr(obj, "_JSONEncoder"): # Use object's custom JSON encoder jsosencode = getattr(obj, "_JSONEncoder") return jsosencode() else: try: s = super().default(obj) except TypeError: # json does not support dumping UserDict but # we can dump the dict stored internally in the # UserDict if isinstance(obj, collections.UserDict): return obj.data # See if the object supports the pickle protocol. # If so, we should be able to use that to serialize. # __getnewargs__ will return bytes for a bytes object # causing an infinte recursion, so we do not # try to pickle bytes or bytearrays if hasattr(obj, "__getnewargs__") and not isinstance( obj, (bytes, bytearray) ): return { "__class__": type(obj).__name__, "__args__": getattr(obj, "__getnewargs__")(), } else: # we cannot convert the object to JSON, just take a string s = str(obj) return s