Restored JSON output of dicts with non-string keys (#179)

* Restored JSON output of dicts with non-string keys

* Use numpy.integer instead of deprecated numpy.int
This commit is contained in:
s-kuberski 2023-05-19 15:58:56 +02:00 committed by GitHub
parent a5b6f69160
commit 81e4f37934
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 7 deletions

View file

@ -188,10 +188,27 @@ def create_json_string(ol, description='', indent=1):
else: else:
raise Exception("Unkown datatype.") raise Exception("Unkown datatype.")
def _jsonifier(o): def _jsonifier(obj):
if isinstance(o, np.int64): if isinstance(obj, dict):
return int(o) result = {}
raise TypeError('%r is not JSON serializable' % o) 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.integer)):
result[str(key)] = obj[key]
else:
raise TypeError('keys must be str, int, float, bool or None')
return result
elif isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
else:
raise ValueError('%r is not JSON serializable' % (obj,))
if indent: if indent:
return json.dumps(d, indent=indent, ensure_ascii=False, default=_jsonifier, write_mode=json.WM_SINGLE_LINE_ARRAY) return json.dumps(d, indent=indent, ensure_ascii=False, default=_jsonifier, write_mode=json.WM_SINGLE_LINE_ARRAY)
@ -200,7 +217,8 @@ def create_json_string(ol, description='', indent=1):
def dump_to_json(ol, fname, description='', indent=1, gz=True): 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 Parameters
---------- ----------
@ -565,7 +583,7 @@ def _ol_from_dict(ind, reps='DICTOBS'):
counter += 1 counter += 1
elif isinstance(v, str): elif isinstance(v, str):
if bool(re.match(r'%s[0-9]+' % (reps), v)): 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 x[k] = v
return x return x
@ -586,7 +604,7 @@ def _ol_from_dict(ind, reps='DICTOBS'):
counter += 1 counter += 1
elif isinstance(e, str): elif isinstance(e, str):
if bool(re.match(r'%s[0-9]+' % (reps), e)): 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) x.append(e)
return x return x

View file

@ -249,6 +249,10 @@ def test_json_dict_io():
with pytest.raises(Exception): with pytest.raises(Exception):
jsonio.dump_dict_to_json(od, fname, description=desc) 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') os.remove(fname + '.json.gz')