Skip to content
2 changes: 1 addition & 1 deletion Pyro5/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ def dumps(self, data):
return msgpack.packb(data, use_bin_type=True, default=self.default)

def loadsCall(self, data):
return msgpack.unpackb(self._convertToBytes(data), raw=False, object_hook=self.object_hook)
return msgpack.unpackb(self._convertToBytes(data), raw=False, object_hook=self.object_hook, ext_hook=self.ext_hook)

def loads(self, data):
return msgpack.unpackb(self._convertToBytes(data), raw=False, object_hook=self.object_hook, ext_hook=self.ext_hook)
Expand Down
43 changes: 43 additions & 0 deletions tests/test_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,49 @@ class TestJsonSerializer(TestSerpentSerializer):
class TestMsgpackSerializer(TestSerpentSerializer):
serializer = Pyro5.serializers.serializers["msgpack"]

import msgpack

class Thing:
def __init__(self, value):
self.value = value

class CustomMsgpackSerializer(Pyro5.serializers.MsgpackSerializer):
CUSTOM_EXT_CODE = 0x40

def default(self, obj):
if isinstance(obj, Thing):
return msgpack.ExtType(self.CUSTOM_EXT_CODE, str(obj.value).encode("ascii"))
return super().default(obj)

def ext_hook(self, code, data):
if code == self.CUSTOM_EXT_CODE:
return Thing(int(data))
return super().ext_hook(code, data)

class TestMsgpackExtHookLoadsCall:
"""Regression: MsgpackSerializer.loadsCall must honor ext_hook so
custom-ExtType-encoded call arguments round-trip when a subclass
overrides ext_hook for custom codes. Without the fix, loadsCall
returns raw msgpack.ExtType objects instead of decoded values."""

serializer = CustomMsgpackSerializer()

def testLoadsCallHonorsExtHook(self):
data = self.serializer.dumpsCall("obj-id", "method-name", (Thing(42),), {})
obj, method, vargs, kwargs = self.serializer.loadsCall(data)
assert obj == "obj-id"
assert method == "method-name"
assert isinstance(vargs[0], Thing)
assert vargs[0].value == 42
assert kwargs == {}

def testLoadsAlreadyHonorsExtHook(self):
"""Sanity check on the sibling that always worked, so future
regressions on either method surface symmetrically."""
data = self.serializer.dumps(Thing(7))
back = self.serializer.loads(data)
assert isinstance(back, Thing)
assert back.value == 7

class TestSerializer2_serpent:
SERIALIZER = "serpent"
Expand Down
Loading