import ctypes


def modify_buffer_object(source_buffer, dest_buffer, nbytes=None):
    """
    Modify a python object that supports the buffer interface internally.
    This is useful for testing things like socket.recv_into()

    dest_buffer must be smaller than source_buffer, or the code will assert.

    :param source_buffer: The source for the new data to be written into dest_buffer.
    :param dest_buffer: The buffer to be modified inline.
    :param nbytes: (OPTIONAL) The maximum number of bytes to write into the dest_buffer.
        If set, the number of bytes written is the minimum of nbytes and the source length.
        Default: None
    :return: The total number of bytes written into dest_buffer.
    """
    assert len(source_buffer) <= len(dest_buffer)
    copy_len = len(source_buffer) if nbytes is None else min(nbytes, source_buffer)
    buffer_ptr = (ctypes.c_byte * len(dest_buffer)).from_buffer(dest_buffer)
    new_value_ptr = (ctypes.c_byte * len(source_buffer)).from_buffer_copy(source_buffer)
    buffer_ptr[:copy_len] = new_value_ptr[:]
    return copy_len