Edit on GitHub

serde.msgpack

Serialize and Deserialize in MsgPack format. This module depends on msgpack package.

  1"""
  2Serialize and Deserialize in MsgPack format. This module depends on
  3[msgpack](https://pypi.org/project/msgpack/) package.
  4"""
  5
  6from typing import Any, Optional, overload
  7
  8import msgpack
  9
 10from .compat import T
 11from .compat import SerdeError
 12from .de import Deserializer, from_dict, from_tuple
 13
 14# Lazy numpy imports to improve startup time
 15from .se import Serializer, to_dict, to_tuple
 16
 17__all__ = ["from_msgpack", "to_msgpack"]
 18
 19
 20class MsgPackSerializer(Serializer[bytes]):
 21    @classmethod
 22    def serialize(
 23        cls, obj: Any, use_bin_type: bool = True, ext_type_code: Optional[int] = None, **opts: Any
 24    ) -> bytes:
 25        if "default" not in opts:
 26            from .numpy import encode_numpy
 27
 28            opts["default"] = encode_numpy
 29        if ext_type_code is not None:
 30            obj_bytes = msgpack.packb(obj, use_bin_type=use_bin_type, **opts)
 31            obj_or_ext = msgpack.ExtType(ext_type_code, obj_bytes)
 32        else:
 33            obj_or_ext = obj
 34        return msgpack.packb(obj_or_ext, use_bin_type=use_bin_type, **opts)
 35
 36
 37class MsgPackDeserializer(Deserializer[bytes]):
 38    @classmethod
 39    def deserialize(
 40        cls, data: bytes, raw: bool = False, use_list: bool = False, **opts: Any
 41    ) -> Any:
 42        return msgpack.unpackb(data, raw=raw, use_list=use_list, **opts)
 43
 44
 45def to_msgpack(
 46    obj: Any,
 47    cls: Optional[Any] = None,
 48    se: type[Serializer[bytes]] = MsgPackSerializer,
 49    named: bool = True,
 50    ext_dict: Optional[dict[type[Any], int]] = None,
 51    reuse_instances: bool = False,
 52    convert_sets: bool = True,
 53    **opts: Any,
 54) -> bytes:
 55    """
 56    Serialize the object into MsgPack.
 57
 58    You can pass any serializable `obj`. If `ext_dict` option is specified, `obj` is encoded
 59    as a `msgpack.ExtType` If you supply other keyword arguments, they will be passed in
 60    `msgpack.packb` function.
 61
 62    * `named`: If `named` is True, field names are preserved, namely the object is encoded as `dict`
 63    then serialized into MsgPack.  If `named` is False, the object is encoded as `tuple` then
 64    serialized into MsgPack. `named=False` will produces compact binary.
 65
 66    * `skip_none`: When set to True, any field in the class with a None value is excluded from the
 67    serialized output. Defaults to False.
 68
 69    If you want to use the other msgpack package, you can subclass `MsgPackSerializer` and
 70    implement your own logic.
 71    """
 72    ext_type_code = None
 73    if ext_dict is not None:
 74        obj_type = type(obj)
 75        ext_type_code = ext_dict.get(obj_type)
 76        if ext_type_code is None:
 77            raise SerdeError(f"Could not find type code for {obj_type.__name__} in ext_dict")
 78
 79    kwargs: Any = {"c": cls, "reuse_instances": reuse_instances, "convert_sets": convert_sets}
 80    dict_or_tuple = to_dict(obj, **kwargs) if named else to_tuple(obj, **kwargs)
 81    return se.serialize(
 82        dict_or_tuple,
 83        ext_type_code=ext_type_code,
 84        **opts,
 85    )
 86
 87
 88@overload
 89def from_msgpack(
 90    c: type[T],
 91    s: bytes,
 92    de: type[Deserializer[bytes]] = MsgPackDeserializer,
 93    named: bool = True,
 94    ext_dict: Optional[dict[int, type[Any]]] = None,
 95    **opts: Any,
 96) -> T: ...
 97
 98
 99@overload
100def from_msgpack(
101    c: Any,
102    s: bytes,
103    de: type[Deserializer[bytes]] = MsgPackDeserializer,
104    named: bool = True,
105    ext_dict: Optional[dict[int, type[Any]]] = None,
106    **opts: Any,
107) -> Any: ...
108
109
110def from_msgpack(
111    c: Any,
112    s: bytes,
113    de: type[Deserializer[bytes]] = MsgPackDeserializer,
114    named: bool = True,
115    ext_dict: Optional[dict[int, type[Any]]] = None,
116    skip_none: bool = False,
117    **opts: Any,
118) -> Any:
119    """
120    Deserialize from MsgPack into the object.
121
122    `c` is a class object and `s` is MsgPack binary. If `ext_dict` option is specified,
123    `c` is ignored and type is inferred from `msgpack.ExtType` If you supply other keyword
124    arguments, they will be passed in `msgpack.unpackb` function.
125
126    If you want to use the other msgpack package, you can subclass `MsgPackDeserializer`
127    and implement your own logic.
128    """
129    if ext_dict is not None:
130        ext = de.deserialize(s, **opts)
131        ext_type = ext_dict.get(ext.code)
132        if ext_type is None:
133            raise SerdeError(f"Could not find type for code {ext.code} in ext_dict")
134        return from_msgpack(ext_type, ext.data, de, named, **opts)
135    else:
136        from_func = from_dict if named else from_tuple
137        return from_func(c, de.deserialize(s, **opts), reuse_instances=False)
def from_msgpack( c: Any, s: bytes, de: type[serde.de.Deserializer[bytes]] = <class 'serde.msgpack.MsgPackDeserializer'>, named: bool = True, ext_dict: Optional[dict[int, type[Any]]] = None, skip_none: bool = False, **opts: Any) -> Any:
111def from_msgpack(
112    c: Any,
113    s: bytes,
114    de: type[Deserializer[bytes]] = MsgPackDeserializer,
115    named: bool = True,
116    ext_dict: Optional[dict[int, type[Any]]] = None,
117    skip_none: bool = False,
118    **opts: Any,
119) -> Any:
120    """
121    Deserialize from MsgPack into the object.
122
123    `c` is a class object and `s` is MsgPack binary. If `ext_dict` option is specified,
124    `c` is ignored and type is inferred from `msgpack.ExtType` If you supply other keyword
125    arguments, they will be passed in `msgpack.unpackb` function.
126
127    If you want to use the other msgpack package, you can subclass `MsgPackDeserializer`
128    and implement your own logic.
129    """
130    if ext_dict is not None:
131        ext = de.deserialize(s, **opts)
132        ext_type = ext_dict.get(ext.code)
133        if ext_type is None:
134            raise SerdeError(f"Could not find type for code {ext.code} in ext_dict")
135        return from_msgpack(ext_type, ext.data, de, named, **opts)
136    else:
137        from_func = from_dict if named else from_tuple
138        return from_func(c, de.deserialize(s, **opts), reuse_instances=False)

Deserialize from MsgPack into the object.

c is a class object and s is MsgPack binary. If ext_dict option is specified, c is ignored and type is inferred from msgpack.ExtType If you supply other keyword arguments, they will be passed in msgpack.unpackb function.

If you want to use the other msgpack package, you can subclass MsgPackDeserializer and implement your own logic.

def to_msgpack( obj: Any, cls: Optional[Any] = None, se: type[serde.se.Serializer[bytes]] = <class 'serde.msgpack.MsgPackSerializer'>, named: bool = True, ext_dict: Optional[dict[type[Any], int]] = None, reuse_instances: bool = False, convert_sets: bool = True, **opts: Any) -> bytes:
46def to_msgpack(
47    obj: Any,
48    cls: Optional[Any] = None,
49    se: type[Serializer[bytes]] = MsgPackSerializer,
50    named: bool = True,
51    ext_dict: Optional[dict[type[Any], int]] = None,
52    reuse_instances: bool = False,
53    convert_sets: bool = True,
54    **opts: Any,
55) -> bytes:
56    """
57    Serialize the object into MsgPack.
58
59    You can pass any serializable `obj`. If `ext_dict` option is specified, `obj` is encoded
60    as a `msgpack.ExtType` If you supply other keyword arguments, they will be passed in
61    `msgpack.packb` function.
62
63    * `named`: If `named` is True, field names are preserved, namely the object is encoded as `dict`
64    then serialized into MsgPack.  If `named` is False, the object is encoded as `tuple` then
65    serialized into MsgPack. `named=False` will produces compact binary.
66
67    * `skip_none`: When set to True, any field in the class with a None value is excluded from the
68    serialized output. Defaults to False.
69
70    If you want to use the other msgpack package, you can subclass `MsgPackSerializer` and
71    implement your own logic.
72    """
73    ext_type_code = None
74    if ext_dict is not None:
75        obj_type = type(obj)
76        ext_type_code = ext_dict.get(obj_type)
77        if ext_type_code is None:
78            raise SerdeError(f"Could not find type code for {obj_type.__name__} in ext_dict")
79
80    kwargs: Any = {"c": cls, "reuse_instances": reuse_instances, "convert_sets": convert_sets}
81    dict_or_tuple = to_dict(obj, **kwargs) if named else to_tuple(obj, **kwargs)
82    return se.serialize(
83        dict_or_tuple,
84        ext_type_code=ext_type_code,
85        **opts,
86    )

Serialize the object into MsgPack.

You can pass any serializable obj. If ext_dict option is specified, obj is encoded as a msgpack.ExtType If you supply other keyword arguments, they will be passed in msgpack.packb function.

  • named: If named is True, field names are preserved, namely the object is encoded as dict then serialized into MsgPack. If named is False, the object is encoded as tuple then serialized into MsgPack. named=False will produces compact binary.

  • skip_none: When set to True, any field in the class with a None value is excluded from the serialized output. Defaults to False.

If you want to use the other msgpack package, you can subclass MsgPackSerializer and implement your own logic.