From 72173178855c72953d2872f72b64e49ed246c3dc Mon Sep 17 00:00:00 2001 From: Simon Kuberski Date: Fri, 19 May 2023 14:14:15 +0200 Subject: [PATCH 1/2] Restored JSON output of dicts with non-string keys --- pyerrors/input/json.py | 32 +++++++++++++++++++++++++------- tests/json_io_test.py | 4 ++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/pyerrors/input/json.py b/pyerrors/input/json.py index 50470bff..7ae344a1 100644 --- a/pyerrors/input/json.py +++ b/pyerrors/input/json.py @@ -188,10 +188,27 @@ def write_Corr_to_dict(my_corr): else: raise Exception("Unkown datatype.") - def _jsonifier(o): - if isinstance(o, np.int64): - return int(o) - raise TypeError('%r is not JSON serializable' % o) + def _jsonifier(obj): + if isinstance(obj, dict): + result = {} + for key in obj: + if key is True: + result['true'] = obj[key] + elif key is False: + result['false'] = obj[key] + elif key is None: + result['null'] = obj[key] + elif isinstance(key, (int, float, np.floating, np.int64)): + result[str(key)] = obj[key] + else: + raise TypeError('keys must be str, int, float, bool or None') + return result + elif isinstance(obj, np.int): + return int(obj) + elif isinstance(obj, np.floating): + return float(obj) + else: + raise ValueError('%r is not JSON serializable' % (obj,)) if indent: return json.dumps(d, indent=indent, ensure_ascii=False, default=_jsonifier, write_mode=json.WM_SINGLE_LINE_ARRAY) @@ -200,7 +217,8 @@ def _jsonifier(o): def dump_to_json(ol, fname, description='', indent=1, gz=True): - """Export a list of Obs or structures containing Obs to a .json(.gz) file + """Export a list of Obs or structures containing Obs to a .json(.gz) file. + Dict keys that are not JSON-serializable such as floats are converted to strings. Parameters ---------- @@ -565,7 +583,7 @@ def dict_replace_obs(d): counter += 1 elif isinstance(v, str): if bool(re.match(r'%s[0-9]+' % (reps), v)): - raise Exception('Dict contains string %s that matches the placeholder! %s Cannot be savely exported.' % (v, reps)) + raise Exception('Dict contains string %s that matches the placeholder! %s Cannot be safely exported.' % (v, reps)) x[k] = v return x @@ -586,7 +604,7 @@ def list_replace_obs(li): counter += 1 elif isinstance(e, str): if bool(re.match(r'%s[0-9]+' % (reps), e)): - raise Exception('Dict contains string %s that matches the placeholder! %s Cannot be savely exported.' % (e, reps)) + raise Exception('Dict contains string %s that matches the placeholder! %s Cannot be safely exported.' % (e, reps)) x.append(e) return x diff --git a/tests/json_io_test.py b/tests/json_io_test.py index 21a70162..dafaaa41 100644 --- a/tests/json_io_test.py +++ b/tests/json_io_test.py @@ -249,6 +249,10 @@ def list_check_obs(l1, l2): with pytest.raises(Exception): jsonio.dump_dict_to_json(od, fname, description=desc) + od = {1: 'test', False: 'True', None: 'None'} + jsonio.dump_dict_to_json(od, fname, description={np.int64(1): np.float64(2.444444)}) + jsonio.dump_dict_to_json(od, fname, description=np.float32(2.444444)) + os.remove(fname + '.json.gz') From 063888a8db7bfe4da56b1cdcd5d8a6af23560afc Mon Sep 17 00:00:00 2001 From: Simon Kuberski Date: Fri, 19 May 2023 14:36:33 +0200 Subject: [PATCH 2/2] Use numpy.integer instead of deprecated numpy.int --- pyerrors/input/json.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyerrors/input/json.py b/pyerrors/input/json.py index 7ae344a1..ca3fb0d2 100644 --- a/pyerrors/input/json.py +++ b/pyerrors/input/json.py @@ -198,12 +198,12 @@ def _jsonifier(obj): result['false'] = obj[key] elif key is None: result['null'] = obj[key] - elif isinstance(key, (int, float, np.floating, np.int64)): + elif isinstance(key, (int, float, np.floating, np.integer)): result[str(key)] = obj[key] else: raise TypeError('keys must be str, int, float, bool or None') return result - elif isinstance(obj, np.int): + elif isinstance(obj, np.integer): return int(obj) elif isinstance(obj, np.floating): return float(obj)