Skip to content

Commit 597f9fd

Browse files
authored
Merge pull request #5204 from chu11/python_bindings_kvs
python: support non-JSON formatted data in KVS
2 parents 7a64e8c + 992459f commit 597f9fd

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

src/bindings/python/flux/kvs.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ def get_key_direct(flux_handle, key):
3535
if valp[0] == ffi.NULL:
3636
return None
3737

38-
ret = json.loads(ffi.string(valp[0]).decode("utf-8"))
38+
try:
39+
ret = json.loads(ffi.string(valp[0]).decode("utf-8"))
40+
except json.decoder.JSONDecodeError:
41+
ret = ffi.string(valp[0]).decode("utf-8")
42+
except UnicodeDecodeError:
43+
ret = ffi.string(valp[0])
3944
RAW.flux_future_destroy(future)
4045
return ret
4146

@@ -78,10 +83,17 @@ def get(flux_handle, key):
7883

7984

8085
def put(flux_handle, key, value):
81-
json_str = json.dumps(value)
8286
if flux_handle.aux_txn is None:
8387
flux_handle.aux_txn = RAW.flux_kvs_txn_create()
84-
return RAW.flux_kvs_txn_put(flux_handle.aux_txn, 0, key, json_str)
88+
try:
89+
json_str = json.dumps(value)
90+
return RAW.flux_kvs_txn_put(flux_handle.aux_txn, 0, key, json_str)
91+
except TypeError:
92+
if isinstance(value, bytes):
93+
return RAW.flux_kvs_txn_put_raw(
94+
flux_handle.aux_txn, 0, key, value, len(value)
95+
)
96+
raise TypeError
8597

8698

8799
def put_mkdir(flux_handle, key):

t/python/t0005-kvs.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,51 @@ def test_kvs_dir_open(self):
3131
with flux.kvs.get_dir(self.f) as d:
3232
self.assertIsNotNone(d)
3333

34-
def set_and_check_context(self, key, value, msg=""):
34+
def set_and_check_context(self, key, value, type):
3535
kd = flux.kvs.KVSDir(self.f)
3636
kd[key] = value
3737
kd.commit()
38-
nv = kd[key]
39-
self.assertEqual(value, nv)
40-
self.assertFalse(isinstance(nv, bytes))
41-
return kd
38+
39+
kd2 = flux.kvs.KVSDir(self.f)
40+
nv = kd2[key]
41+
if isinstance(value, bytes) and type is str:
42+
self.assertEqual(value.decode('utf-8'), nv)
43+
else:
44+
self.assertEqual(value, nv)
45+
if type is not None:
46+
self.assertTrue(isinstance(nv, type))
47+
48+
return kd2
4249

4350
def test_set_int(self):
44-
self.set_and_check_context("int", 10)
51+
self.set_and_check_context("int", 10, int)
4552

4653
def test_set_float(self):
47-
self.set_and_check_context("float", 10.5)
54+
self.set_and_check_context("float", 10.5, float)
4855

4956
def test_set_string(self):
50-
self.set_and_check_context("string", "stuff")
57+
self.set_and_check_context("string", "stuff", str)
58+
59+
def test_set_none(self):
60+
self.set_and_check_context("none", None, None)
5161

5262
def test_set_unicode(self):
53-
self.set_and_check_context("unicode", "\u32db \u263a \u32e1")
63+
self.set_and_check_context("unicode", "\u32db \u263a \u32e1", str)
64+
65+
def test_set_bytes(self):
66+
self.set_and_check_context("bytes", bytes.fromhex("deadbeef"), bytes)
5467

5568
def test_set_list(self):
56-
self.set_and_check_context("list", [1, 2, 3, 4])
69+
self.set_and_check_context("list", [1, 2, 3, 4], list)
5770

5871
def test_set_dict(self):
5972
self.set_and_check_context(
60-
"dict", {"thing": "stuff", "other thing": "more stuff"}
73+
"dict", {"thing": "stuff", "other thing": "more stuff"}, dict
6174
)
6275

76+
def test_set_not_legal_json(self):
77+
self.set_and_check_context("badjson", b"{", str)
78+
6379
def test_exists_dir(self):
6480
with flux.kvs.get_dir(self.f) as kd:
6581
kd.mkdir("pytestdir")
@@ -79,7 +95,7 @@ def test_commit_flags(self):
7995
self.assertTrue(flux.kvs.exists(self.f, "flagcheck"))
8096

8197
def test_remove(self):
82-
kd = self.set_and_check_context("todel", "things to delete")
98+
kd = self.set_and_check_context("todel", "things to delete", str)
8399
del kd["todel"]
84100
kd.commit()
85101
with self.assertRaises(KeyError):
@@ -96,7 +112,7 @@ def test_fill(self):
96112
self.assertEqual(kd["dir"]["other_thing"], "dirstuff")
97113

98114
def test_set_deep(self):
99-
self.set_and_check_context("a.b.c.e.f.j.k", 5)
115+
self.set_and_check_context("a.b.c.e.f.j.k", 5, int)
100116

101117
def test_bad_init(self):
102118
with self.assertRaises(ValueError):

0 commit comments

Comments
 (0)