diff --git a/msgpack/__init__.py b/msgpack/__init__.py index f3266b70..f56757b7 100644 --- a/msgpack/__init__.py +++ b/msgpack/__init__.py @@ -2,7 +2,7 @@ import os from .exceptions import * # noqa: F403 -from .ext import ExtType, Timestamp +from .ext import Bypass, ExtType, Timestamp version = (1, 1, 2) __version__ = "1.1.2" diff --git a/msgpack/_packer.pyx b/msgpack/_packer.pyx index 94d1462c..eaa45fca 100644 --- a/msgpack/_packer.pyx +++ b/msgpack/_packer.pyx @@ -8,7 +8,7 @@ from cpython.datetime cimport ( cdef ExtType cdef Timestamp -from .ext import ExtType, Timestamp +from .ext import ExtType, Timestamp, Bypass cdef extern from "Python.h": @@ -222,6 +222,8 @@ cdef class Packer: llval = o.seconds ulval = o.nanoseconds msgpack_pack_timestamp(&self.pk, llval, ulval) + elif type(o) is Bypass: + msgpack_pack_raw_body(&self.pk, o.data, len(o.data)) elif PyList_CheckExact(o) if strict else (PyTuple_Check(o) or PyList_Check(o)): L = Py_SIZE(o) if L > ITEM_LIMIT: diff --git a/msgpack/ext.py b/msgpack/ext.py index 9694819a..c9a954d9 100644 --- a/msgpack/ext.py +++ b/msgpack/ext.py @@ -16,6 +16,19 @@ def __new__(cls, code, data): return super().__new__(cls, code, data) +class Bypass: + """Bypass is a placeholder class to skip serialization and pass the bytes value as is.""" + + __slots__ = ["data"] + + def __init__(self, data): + if isinstance(data, bytes): + self.data = data + + else: + self.data = memoryview(data).tobytes() + + class Timestamp: """Timestamp represents the Timestamp extension type in msgpack. diff --git a/msgpack/fallback.py b/msgpack/fallback.py index b02e47cf..fcff0bd2 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -38,7 +38,7 @@ def newlist_hint(size): from .exceptions import BufferFull, ExtraData, FormatError, OutOfData, StackError -from .ext import ExtType, Timestamp +from .ext import Bypass, ExtType, Timestamp EX_SKIP = 0 EX_CONSTRUCT = 1 @@ -773,6 +773,9 @@ def _pack( self._buffer.write(struct.pack("b", code)) self._buffer.write(data) return + if check(obj, Bypass): + self._buffer.write(obj.data) + return if check(obj, list_types): n = len(obj) self._pack_array_header(n)