def _python_set_to_native(typ, obj, c, size, setptr, errorptr):
    """
    Construct a new native set from a Python set.
    """
    # Allocate a new native set
    ok, inst = setobj.SetInstance.allocate_ex(c.context, c.builder, typ, size)
    with c.builder.if_else(ok, likely=True) as (if_ok, if_not_ok):
        with if_ok:
            # Traverse Python set and unbox objects into native set
            typobjptr = cgutils.alloca_once_value(c.builder,
                                                  ir.Constant(c.pyapi.pyobj, None))

            with c.pyapi.set_iterate(obj) as loop:
                itemobj = loop.value
                # Mandate that objects all have the same exact type
                typobj = c.pyapi.get_type(itemobj)
                expected_typobj = c.builder.load(typobjptr)

                with c.builder.if_else(
                    cgutils.is_null(c.builder, expected_typobj),
                    likely=False) as (if_first, if_not_first):
                    with if_first:
                        # First iteration => store item type
                        c.builder.store(typobj, typobjptr)
                    with if_not_first:
                        # Otherwise, check item type
                        type_mismatch = c.builder.icmp_signed('!=', typobj,
                                                              expected_typobj)
                        with c.builder.if_then(type_mismatch, likely=False):
                            c.builder.store(cgutils.true_bit, errorptr)
                            c.pyapi.err_set_string("PyExc_TypeError",
                                                   "can't unbox heterogeneous set")
                            loop.do_break()

                # XXX we don't call native cleanup for each set element,
                # since that would require keeping track
                # of which unboxings have been successful.
                native = c.unbox(typ.dtype, itemobj)
                with c.builder.if_then(native.is_error, likely=False):
                    c.builder.store(cgutils.true_bit, errorptr)
                inst.add_pyapi(c.pyapi, native.value, do_resize=False)

            if typ.reflected:
                inst.parent = obj
            # Associate meminfo pointer with the Python object for later reuse.
            with c.builder.if_then(c.builder.not_(c.builder.load(errorptr)),
                                   likely=False):
                c.pyapi.object_set_private_data(obj, inst.meminfo)
            inst.set_dirty(False)
            c.builder.store(inst.value, setptr)

        with if_not_ok:
            c.builder.store(cgutils.true_bit, errorptr)

    # If an error occurred, drop the whole native set
    with c.builder.if_then(c.builder.load(errorptr)):
        c.context.nrt.decref(c.builder, typ, inst.value)

    Construct a new native set from a Python set.
    
numba/core/new_boxing.py