diff --git a/swh/core/api/serializers.py b/swh/core/api/serializers.py --- a/swh/core/api/serializers.py +++ b/swh/core/api/serializers.py @@ -90,6 +90,7 @@ class MsgpackExtTypeCodes(Enum): LONG_INT = 1 + LONG_NEG_INT = 2 def encode_data_client(data: Any, extra_encoders=None) -> bytes: @@ -224,12 +225,15 @@ def encode_types(obj): if isinstance(obj, int): # integer overflowed while packing. Handle it as an extended type + if obj > 0: + code = MsgpackExtTypeCodes.LONG_INT.value + else: + code = MsgpackExtTypeCodes.LONG_NEG_INT.value + obj = -obj length, rem = divmod(obj.bit_length(), 8) if rem: length += 1 - return msgpack.ExtType( - MsgpackExtTypeCodes.LONG_INT.value, int.to_bytes(obj, length, "big") - ) + return msgpack.ExtType(code, int.to_bytes(obj, length, "big")) if isinstance(obj, types.GeneratorType): return list(obj) @@ -259,6 +263,8 @@ def ext_hook(code, data): if code == MsgpackExtTypeCodes.LONG_INT.value: return int.from_bytes(data, "big") + elif code == MsgpackExtTypeCodes.LONG_NEG_INT.value: + return -int.from_bytes(data, "big") raise ValueError("Unknown msgpack extended code %s" % code) def decode_types(obj): diff --git a/swh/core/api/tests/test_serializers.py b/swh/core/api/tests/test_serializers.py --- a/swh/core/api/tests/test_serializers.py +++ b/swh/core/api/tests/test_serializers.py @@ -171,6 +171,7 @@ **DATA, "none_dict_key": {None: 42}, "long_int_is_loooong": 10000000000000000000000000000000, + "long_negative_int_is_loooong": -10000000000000000000000000000000, } data = msgpack_dumps(expected_original_data) actual_data = msgpack_loads(data)