.. versionadded:: 2018.3.4

    Wraps msgpack.pack and ensures that the passed object is unwrapped if it is
    a proxy.

    By default, this function uses the msgpack module and falls back to
    msgpack_pure, if the msgpack is not available. You can pass an alternate
    msgpack module using the _msgpack_module argument.

def pack(o, stream, **kwargs):
    '''
    .. versionadded:: 2018.3.4

    Wraps msgpack.pack and ensures that the passed object is unwrapped if it is
    a proxy.

    By default, this function uses the msgpack module and falls back to
    msgpack_pure, if the msgpack is not available. You can pass an alternate
    msgpack module using the _msgpack_module argument.
    '''
    msgpack_module = kwargs.pop('_msgpack_module', msgpack)
    orig_enc_func = kwargs.pop('default', lambda x: x)

    def _enc_func(obj):
        obj = ThreadLocalProxy.unproxy(obj)
        return orig_enc_func(obj)

    return msgpack_module.pack(o, stream, default=_enc_func, **kwargs)