Skip to content

Commit c92b9c7

Browse files
committed
Add msgpack support for message serialization in Session
1 parent 6ec7306 commit c92b9c7

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
### Enhancements made
1010

1111
- Support psutil for finding network addresses [#1033](https://github.com/jupyter/jupyter_client/pull/1033) ([@juliangilbey](https://github.com/juliangilbey))
12-
- Add new functions `orjson_packer` and `orjson_unpacker`.
12+
- Add new functions `orjson_packer`, `orjson_unpacker`, `msgpack_packer` and `msgpack_unpacker`
1313

1414
### Bugs fixed
1515

jupyter_client/session.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# Distributed under the terms of the Modified BSD License.
1313
from __future__ import annotations
1414

15+
import functools
1516
import hashlib
1617
import hmac
1718
import json
@@ -132,15 +133,22 @@ def json_unpacker(s: str | bytes) -> t.Any:
132133
_default_packer_unpacker = "json", "json"
133134
_default_pack_unpack = (json_packer, json_unpacker)
134135
else:
135-
import functools
136-
137136
orjson_packer = functools.partial(
138137
orjson.dumps, default=json_default, option=orjson.OPT_NAIVE_UTC | orjson.OPT_UTC_Z
139138
)
140139
orjson_unpacker = orjson.loads
141140
_default_packer_unpacker = "orjson", "orjson"
142141
_default_pack_unpack = (orjson_packer, orjson_unpacker)
143142

143+
try:
144+
import msgpack # type:ignore[import-not-found]
145+
146+
except ModuleNotFoundError:
147+
msgpack = None
148+
else:
149+
msgpack_packer = functools.partial(msgpack.packb, default=json_default)
150+
msgpack_unpacker = msgpack.unpackb
151+
144152

145153
def pickle_packer(o: t.Any) -> bytes:
146154
"""Pack an object using the pickle module."""
@@ -331,7 +339,7 @@ class Session(Configurable):
331339
332340
debug : bool
333341
whether to trigger extra debugging statements
334-
packer/unpacker : str : 'json', 'pickle' or import_string
342+
packer/unpacker : str : 'orjson', 'json', 'pickle', 'msgpack' or import_string
335343
importstrings for methods to serialize message parts. If just
336344
'json' or 'pickle', predefined JSON and pickle packers will be used.
337345
Otherwise, the entire importstring must be used.
@@ -399,6 +407,10 @@ def _packer_unpacker_changed(self, change: t.Any) -> None:
399407
self.pack = pickle_packer
400408
self.unpack = pickle_unpacker
401409
self.packer = self.unpacker = new
410+
elif new_ == "msgpack":
411+
self.pack = msgpack_packer
412+
self.unpack = msgpack_unpacker
413+
self.packer = self.unpacker = new
402414
else:
403415
obj = import_item(str(new))
404416
name = "pack" if change["name"] == "packer" else "unpack"
@@ -523,7 +535,7 @@ def __init__(self, **kwargs: t.Any) -> None:
523535
524536
debug : bool
525537
whether to trigger extra debugging statements
526-
packer/unpacker : str : 'json', 'pickle' or import_string
538+
packer/unpacker : str : 'orjson', 'json', 'pickle', 'msgpack' or import_string
527539
importstrings for methods to serialize message parts. If just
528540
'json' or 'pickle', predefined JSON and pickle packers will be used.
529541
Otherwise, the entire importstring must be used.

tests/test_session.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ def session():
4747
]
4848
if ss.orjson:
4949
serializers.append(("orjson", ss.orjson_packer, ss.orjson_unpacker))
50+
if ss.msgpack:
51+
serializers.append(("msgpack", ss.msgpack_packer, ss.msgpack_unpacker))
5052

5153

5254
@pytest.mark.usefixtures("no_copy_threshold")
@@ -537,7 +539,7 @@ def test_serialize_objects(packer, pack, unpack, description, data):
537539
warnings.simplefilter("ignore")
538540
value = pack(data_in)
539541
unpacked = unpack(value)
540-
if (description == "infinite") and (packer == "pickle"):
542+
if (description == "infinite") and (packer in ["pickle", "msgpack"]):
541543
assert math.isinf(unpacked)
542544
return
543545
assert unpacked in data_out_options
@@ -552,7 +554,7 @@ def test_cannot_serialize(session, packer, pack, unpack):
552554

553555
@pytest.mark.parametrize("mode", ["packer", "unpacker"])
554556
@pytest.mark.parametrize(["packer", "pack", "unpack"], serializers)
555-
def test_packer_unpacker(session, packer, pack, unpack, mode):
557+
def test_pack_unpack(session, packer, pack, unpack, mode):
556558
s: ss.Session = session
557559
s.set_trait(mode, packer)
558560
assert s.pack is pack

0 commit comments

Comments
 (0)