def _make_dgl_args(args, temp_args):
    """Pack arguments into c args dgl call accept.

    temp_args is used to temporarily save the arguments so they will not be
    freed during C API function call.
    """
    num_args = len(args)
    values = (DGLValue * num_args)()
    type_codes = (ctypes.c_int * num_args)()
    for i, arg in enumerate(args):
        if arg is None:
            values[i].v_handle = None
            type_codes[i] = TypeCode.NULL
        elif isinstance(arg, ObjectBase):
            values[i].v_handle = arg.handle
            type_codes[i] = TypeCode.OBJECT_HANDLE
        elif isinstance(arg, (list, tuple, dict, ObjectGeneric)):
            arg = convert_to_object(arg)
            values[i].v_handle = arg.handle
            type_codes[i] = TypeCode.OBJECT_HANDLE
            temp_args.append(arg)
        elif isinstance(arg, NDArrayBase):
            values[i].v_handle = ctypes.cast(arg.handle, ctypes.c_void_p)
            type_codes[i] = (
                TypeCode.NDARRAY_CONTAINER
                if not arg.is_view
                else TypeCode.ARRAY_HANDLE
            )
        elif isinstance(arg, _nd._DGL_COMPATS):
            values[i].v_handle = ctypes.c_void_p(arg._dgl_handle)
            type_codes[i] = arg.__class__._dgl_tcode
        elif isinstance(arg, Integral):
            values[i].v_int64 = arg
            type_codes[i] = TypeCode.INT
        elif isinstance(arg, Number):
            values[i].v_float64 = arg
            type_codes[i] = TypeCode.FLOAT
        elif isinstance(arg, DGLDataType):
            values[i].v_str = c_str(str(arg))
            type_codes[i] = TypeCode.STR
        elif isinstance(arg, DGLContext):
            values[i].v_ctx = arg
            type_codes[i] = TypeCode.DGL_CONTEXT
        elif isinstance(arg, bytearray):
            arr = DGLByteArray()
            arr.data = ctypes.cast(
                (ctypes.c_byte * len(arg)).from_buffer(arg),
                ctypes.POINTER(ctypes.c_byte),
            )
            arr.size = len(arg)
            values[i].v_handle = ctypes.c_void_p(ctypes.addressof(arr))
            temp_args.append(arr)
            type_codes[i] = TypeCode.BYTES
        elif isinstance(arg, string_types):
            values[i].v_str = c_str(arg)
            type_codes[i] = TypeCode.STR
        # NOTE(minjie): module is not used in DGL
        # elif isinstance(arg, _CLASS_MODULE):
        #    values[i].v_handle = arg.handle
        #    type_codes[i] = TypeCode.MODULE_HANDLE
        elif isinstance(arg, FunctionBase):
            values[i].v_handle = arg.handle
            type_codes[i] = TypeCode.FUNC_HANDLE
        elif isinstance(arg, ctypes.c_void_p):
            values[i].v_handle = arg
            type_codes[i] = TypeCode.HANDLE
        elif callable(arg):
            arg = convert_to_dgl_func(arg)
            values[i].v_handle = arg.handle
            type_codes[i] = TypeCode.FUNC_HANDLE
            temp_args.append(arg)
        else:
            raise TypeError("Don't know how to handle type %s" % type(arg))
    return values, type_codes, num_args
Pack arguments into c args dgl call accept.

    temp_args is used to temporarily save the arguments so they will not be
    freed during C API function call.
    
python/dgl/_ffi/_ctypes/function.py