
/* set object implementation

   Written and maintained by Raymond D. Hettinger <python@rcn.com>
   Derived from Objects/dictobject.c.

   The basic lookup function used by all operations.
   This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.

   The initial probe index is computed as hash mod the table size.
   Subsequent probe indices are computed as explained in Objects/dictobject.c.

   To improve cache locality, each probe inspects a series of consecutive
   nearby entries before moving on to probes elsewhere in memory.  This leaves
   us with a hybrid of linear probing and randomized probing.  The linear probing
   reduces the cost of hash collisions because consecutive memory accesses
   tend to be much cheaper than scattered probes.  After LINEAR_PROBES steps,
   we then use more of the upper bits from the hash value and apply a simple
   linear congruential random number generator.  This helps break-up long
   chains of collisions.

   All arithmetic on hash should ignore overflow.

   Unlike the dictionary implementation, the lookkey function can return
   NULL if the rich comparison returns an error.

   Use cases for sets differ considerably from dictionaries where looked-up
   keys are more likely to be present.  In contrast, sets are primarily
   about membership testing where the presence of an element is not known in
   advance.  Accordingly, the set implementation needs to optimize for both
   the found and not-found case.
*/

#include "Python.h"
#include "pycore_ceval.h"               // _PyEval_GetBuiltin()
#include "pycore_critical_section.h"    // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
#include "pycore_dict.h"                // _PyDict_Contains_KnownHash()
#include "pycore_modsupport.h"          // _PyArg_NoKwnames()
#include "pycore_object.h"              // _PyObject_GC_UNTRACK()
#include "pycore_pyatomic_ft_wrappers.h"  // FT_ATOMIC_LOAD_SSIZE_RELAXED()
#include "pycore_pyerrors.h"            // _PyErr_SetKeyError()
#include "pycore_setobject.h"           // _PySet_NextEntry() definition
#include "pycore_weakref.h"             // FT_CLEAR_WEAKREFS()

#include "stringlib/eq.h"               // unicode_eq()
#include <stddef.h>                     // offsetof()
#include "clinic/setobject.c.h"

/*[clinic input]
class set "PySetObject *" "&PySet_Type"
class frozenset "PySetObject *" "&PyFrozenSet_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=97ad1d3e9f117079]*/

/*[python input]
class setobject_converter(self_converter):
    type = "PySetObject *"
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=33a44506d4d57793]*/

/* Object used as dummy key to fill deleted entries */
static PyObject _dummy_struct;

#define dummy (&_dummy_struct)

#define SET_LOOKKEY_FOUND 1
#define SET_LOOKKEY_NO_MATCH 0
#define SET_LOOKKEY_ERROR (-1)
#define SET_LOOKKEY_CHANGED (-2)
#define SET_LOOKKEY_EMPTY (-3)

typedef int (*compare_func)(PySetObject *so, setentry *table, setentry *ep,
                            PyObject *key, Py_hash_t hash);

#ifdef Py_GIL_DISABLED

#define SET_IS_SHARED(so) _PyObject_GC_IS_SHARED(so)
#define SET_MARK_SHARED(so) _PyObject_GC_SET_SHARED(so)

static void
ensure_shared_on_read(PySetObject *so)
{
    if (!_Py_IsOwnedByCurrentThread((PyObject *)so) && !SET_IS_SHARED(so)) {
        // The first time we access a set from a non-owning thread we mark it
        // as shared. This ensures that a concurrent resize operation will
        // delay freeing the old entries using QSBR, which is necessary
        // to safely allow concurrent reads without locking...
        Py_BEGIN_CRITICAL_SECTION(so);
        if (!SET_IS_SHARED(so)) {
            SET_MARK_SHARED(so);
        }
        Py_END_CRITICAL_SECTION();
    }
}

static inline Py_ALWAYS_INLINE int
set_compare_threadsafe(PySetObject *so, setentry *table, setentry *ep,
                       PyObject *key, Py_hash_t hash)
{
    PyObject *startkey = FT_ATOMIC_LOAD_PTR_ACQUIRE(ep->key);
    if (startkey == NULL) {
        return SET_LOOKKEY_EMPTY;
    }
    if (startkey == key) {
        return SET_LOOKKEY_FOUND;
    }
    Py_ssize_t ep_hash = FT_ATOMIC_LOAD_SSIZE_ACQUIRE(ep->hash);
    if (ep_hash == hash) {
        if (!_Py_TryIncrefCompare(&ep->key, startkey)) {
            return SET_LOOKKEY_CHANGED;
        }
        int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
        Py_DECREF(startkey);
        if (cmp < 0) {
            return SET_LOOKKEY_ERROR;
        }
        if (table == FT_ATOMIC_LOAD_PTR_ACQUIRE(so->table) &&
            startkey == FT_ATOMIC_LOAD_PTR_ACQUIRE(ep->key)) {
            assert(cmp == SET_LOOKKEY_FOUND || cmp == SET_LOOKKEY_NO_MATCH);
            return cmp;
        }
        else {
            /* The set was mutated, restart */
            return SET_LOOKKEY_CHANGED;
        }
    }
    return SET_LOOKKEY_NO_MATCH;
}

#else

#define SET_IS_SHARED(so) 0
#define SET_MARK_SHARED(so)

#endif

static inline Py_ALWAYS_INLINE int
set_compare_entry_lock_held(PySetObject *so, setentry *table, setentry *entry,
                            PyObject *key, Py_hash_t hash)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    if (entry->hash == 0 && entry->key == NULL)
        return SET_LOOKKEY_EMPTY;
    if (entry->hash == hash) {
        PyObject *startkey = entry->key;
        assert(startkey != dummy);
        if (startkey == key)
            return SET_LOOKKEY_FOUND;
        if (PyUnicode_CheckExact(startkey)
            && PyUnicode_CheckExact(key)
            && unicode_eq(startkey, key))
            return SET_LOOKKEY_FOUND;
        table = so->table;
        Py_INCREF(startkey);
        int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
        Py_DECREF(startkey);
        if (cmp < 0)
            return SET_LOOKKEY_ERROR;
        if (table != so->table || entry->key != startkey)
            return SET_LOOKKEY_CHANGED;
        if (cmp > 0)
            return SET_LOOKKEY_FOUND;
    }
    return SET_LOOKKEY_NO_MATCH;
}

// This is similar to set_compare_entry_lock_held() but we don't need to
// incref startkey before comparing and we don't need to check if the set has
// changed.  This also omits the PyUnicode_CheckExact() special case since it
// doesn't help much for frozensets.
static inline Py_ALWAYS_INLINE int
set_compare_frozenset(PySetObject *so, setentry *table, setentry *ep,
                                 PyObject *key, Py_hash_t hash)
{
    assert(PyFrozenSet_Check(so));
    PyObject *startkey = ep->key;
    if (startkey == NULL) {
        return SET_LOOKKEY_EMPTY;
    }
    if (startkey == key) {
        return SET_LOOKKEY_FOUND;
    }
    Py_ssize_t ep_hash = ep->hash;
    if (ep_hash == hash) {
        int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
        if (cmp < 0) {
            return SET_LOOKKEY_ERROR;
        }
        assert(cmp == SET_LOOKKEY_FOUND || cmp == SET_LOOKKEY_NO_MATCH);
        return cmp;
    }
    return SET_LOOKKEY_NO_MATCH;
}

static void
set_zero_table(setentry *table, size_t size)
{
#ifdef Py_GIL_DISABLED
    for (size_t i = 0; i < size; i++) {
        setentry *entry = &table[i];
        FT_ATOMIC_STORE_SSIZE_RELAXED(entry->hash, 0);
        FT_ATOMIC_STORE_PTR_RELEASE(entry->key, NULL);
    }
#else
    memset(table, 0, sizeof(setentry)*size);
#endif
}

/* ======================================================================== */
/* ======= Begin logic for probing the hash table ========================= */

/* Set this to zero to turn-off linear probing */
#ifndef LINEAR_PROBES
#define LINEAR_PROBES 9
#endif

/* This must be >= 1 */
#define PERTURB_SHIFT 5

static int
set_do_lookup(PySetObject *so, setentry *table, size_t mask, PyObject *key,
              Py_hash_t hash, setentry **epp, compare_func compare_entry)
{
    setentry *entry;
    size_t perturb = hash;
    size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
    int probes;
    int status;

    while (1) {
        entry = &table[i];
        probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
        do {
            status = compare_entry(so, table, entry, key, hash);
            if (status != SET_LOOKKEY_NO_MATCH) {
                if (status == SET_LOOKKEY_EMPTY) {
                    return SET_LOOKKEY_NO_MATCH;
                }
                *epp = entry;
                return status;
            }
            entry++;
        } while (probes--);
        perturb >>= PERTURB_SHIFT;
        i = (i * 5 + 1 + perturb) & mask;
    }
    Py_UNREACHABLE();
}

static int set_table_resize(PySetObject *, Py_ssize_t);

static int
set_add_entry_takeref(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    setentry *table;
    setentry *freeslot;
    setentry *entry;
    size_t perturb;
    size_t mask;
    size_t i;                       /* Unsigned for defined overflow behavior */
    int probes;
    int cmp;

  restart:

    mask = so->mask;
    i = (size_t)hash & mask;
    freeslot = NULL;
    perturb = hash;

    while (1) {
        entry = &so->table[i];
        probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
        do {
            if (entry->hash == 0 && entry->key == NULL)
                goto found_unused_or_dummy;
            if (entry->hash == hash) {
                PyObject *startkey = entry->key;
                assert(startkey != dummy);
                if (startkey == key)
                    goto found_active;
                if (PyUnicode_CheckExact(startkey)
                    && PyUnicode_CheckExact(key)
                    && unicode_eq(startkey, key))
                    goto found_active;
                table = so->table;
                Py_INCREF(startkey);
                cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
                Py_DECREF(startkey);
                if (cmp > 0)
                    goto found_active;
                if (cmp < 0)
                    goto comparison_error;
                if (table != so->table || entry->key != startkey)
                    goto restart;
                mask = so->mask;
            }
            else if (entry->hash == -1) {
                assert (entry->key == dummy);
                freeslot = entry;
            }
            entry++;
        } while (probes--);
        perturb >>= PERTURB_SHIFT;
        i = (i * 5 + 1 + perturb) & mask;
    }

  found_unused_or_dummy:
    if (freeslot == NULL)
        goto found_unused;
    if (freeslot->hash != -1) {
        goto restart;
    }
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used + 1);
    FT_ATOMIC_STORE_SSIZE_RELAXED(freeslot->hash, hash);
    FT_ATOMIC_STORE_PTR_RELEASE(freeslot->key, key);
    return 0;

  found_unused:
    so->fill++;
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used + 1);
    FT_ATOMIC_STORE_SSIZE_RELAXED(entry->hash, hash);
    FT_ATOMIC_STORE_PTR_RELEASE(entry->key, key);
    if ((size_t)so->fill*5 < mask*3)
        return 0;
    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);

  found_active:
    Py_DECREF(key);
    return 0;

  comparison_error:
    Py_DECREF(key);
    return -1;
}

static int
set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);

    return set_add_entry_takeref(so, Py_NewRef(key), hash);
}

static void
set_unhashable_type(PyObject *key)
{
    PyObject *exc = PyErr_GetRaisedException();
    assert(exc != NULL);
    if (!Py_IS_TYPE(exc, (PyTypeObject*)PyExc_TypeError)) {
        PyErr_SetRaisedException(exc);
        return;
    }

    PyErr_Format(PyExc_TypeError,
                 "cannot use '%T' as a set element (%S)",
                 key, exc);
    Py_DECREF(exc);
}

int
_PySet_AddTakeRef(PySetObject *so, PyObject *key)
{
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1) {
        set_unhashable_type(key);
        Py_DECREF(key);
        return -1;
    }
    // We don't pre-increment here, the caller holds a strong
    // reference to the object which we are stealing.
    return set_add_entry_takeref(so, key, hash);
}

/*
Internal routine used by set_table_resize() to insert an item which is
known to be absent from the set.  Besides the performance benefit,
there is also safety benefit since using set_add_entry() risks making
a callback in the middle of a set_table_resize(), see issue 1456209.
The caller is responsible for updating the key's reference count and
the setobject's fill and used fields.
*/
static void
set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
{
    setentry *entry;
    size_t perturb = hash;
    size_t i = (size_t)hash & mask;
    size_t j;

    while (1) {
        entry = &table[i];
        if (entry->key == NULL)
            goto found_null;
        if (i + LINEAR_PROBES <= mask) {
            for (j = 0; j < LINEAR_PROBES; j++) {
                entry++;
                if (entry->key == NULL)
                    goto found_null;
            }
        }
        perturb >>= PERTURB_SHIFT;
        i = (i * 5 + 1 + perturb) & mask;
    }
  found_null:
    FT_ATOMIC_STORE_SSIZE_RELAXED(entry->hash, hash);
    FT_ATOMIC_STORE_PTR_RELEASE(entry->key, key);
}

/* ======== End logic for probing the hash table ========================== */
/* ======================================================================== */

static int
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash, setentry **epp)
{
    int status;
    if (PyFrozenSet_CheckExact(so)) {
        status = set_do_lookup(so, so->table, so->mask, key, hash, epp,
                               set_compare_frozenset);
    }
    else {
        Py_BEGIN_CRITICAL_SECTION(so);
        do {
            status = set_do_lookup(so, so->table, so->mask, key, hash, epp,
                                   set_compare_entry_lock_held);
        } while (status == SET_LOOKKEY_CHANGED);
        Py_END_CRITICAL_SECTION();
    }
    assert(status == SET_LOOKKEY_FOUND ||
           status == SET_LOOKKEY_NO_MATCH ||
           status == SET_LOOKKEY_ERROR);
    return status;
}

#ifdef Py_GIL_DISABLED
static int
set_lookkey_threadsafe(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    int status;
    setentry *entry;
    if (PyFrozenSet_CheckExact(so)) {
        status = set_do_lookup(so, so->table, so->mask, key, hash, &entry,
                               set_compare_frozenset);
        assert(status == SET_LOOKKEY_FOUND ||
               status == SET_LOOKKEY_NO_MATCH ||
               status == SET_LOOKKEY_ERROR);
        return status;
    }
    ensure_shared_on_read(so);
    setentry *table = FT_ATOMIC_LOAD_PTR_ACQUIRE(so->table);
    size_t mask = FT_ATOMIC_LOAD_SSIZE_ACQUIRE(so->mask);
    if (table == NULL || table != FT_ATOMIC_LOAD_PTR_ACQUIRE(so->table)) {
        return set_lookkey(so, key, hash, &entry);
    }
    status = set_do_lookup(so, table, mask, key, hash, &entry,
                           set_compare_threadsafe);
    if (status == SET_LOOKKEY_CHANGED) {
        return set_lookkey(so, key, hash, &entry);
    }
    assert(status == SET_LOOKKEY_FOUND ||
           status == SET_LOOKKEY_NO_MATCH ||
           status == SET_LOOKKEY_ERROR);
    return status;
}
#endif

static void free_entries(setentry *entries, size_t size, bool use_qsbr)
{
#ifdef Py_GIL_DISABLED
    if (use_qsbr) {
        _PyMem_FreeDelayed(entries, size * sizeof(setentry));
        return;
    }
#endif
    PyMem_Free(entries);
}

/*
Restructure the table by allocating a new table and reinserting all
keys again.  When entries have been deleted, the new table may
actually be smaller than the old one.
*/
static int
set_table_resize(PySetObject *so, Py_ssize_t minused)
{
    setentry *oldtable, *newtable, *entry;
    Py_ssize_t oldmask = so->mask;
    Py_ssize_t oldsize = (size_t)oldmask + 1;
    size_t newmask;
    int is_oldtable_malloced;
    setentry small_copy[PySet_MINSIZE];

    assert(minused >= 0);

    /* Find the smallest table size > minused. */
    /* XXX speed-up with intrinsics */
    size_t newsize = PySet_MINSIZE;
    while (newsize <= (size_t)minused) {
        newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
    }

    /* Get space for a new table. */
    oldtable = so->table;
    assert(oldtable != NULL);
    is_oldtable_malloced = oldtable != so->smalltable;

    if (newsize == PySet_MINSIZE) {
        /* A large table is shrinking, or we can't get any smaller. */
        newtable = so->smalltable;
        if (newtable == oldtable) {
            if (so->fill == so->used) {
                /* No dummies, so no point doing anything. */
                return 0;
            }
            /* We're not going to resize it, but rebuild the
               table anyway to purge old dummy entries.
               Subtle:  This is *necessary* if fill==size,
               as set_lookkey needs at least one virgin slot to
               terminate failing searches.  If fill < size, it's
               merely desirable, as dummies slow searches. */
            assert(so->fill > so->used);
            memcpy(small_copy, oldtable, sizeof(small_copy));
            oldtable = small_copy;
        }
    }
    else {
        newtable = PyMem_NEW(setentry, newsize);
        if (newtable == NULL) {
            PyErr_NoMemory();
            return -1;
        }
    }

    /* Make the set empty, using the new table. */
    assert(newtable != oldtable);
    set_zero_table(newtable, newsize);
    FT_ATOMIC_STORE_PTR_RELEASE(so->table, NULL);
    FT_ATOMIC_STORE_SSIZE_RELEASE(so->mask, newsize - 1);

    /* Copy the data over; this is refcount-neutral for active entries;
       dummy entries aren't copied over, of course */
    newmask = (size_t)so->mask;
    if (so->fill == so->used) {
        for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
            if (entry->key != NULL) {
                set_insert_clean(newtable, newmask, entry->key, entry->hash);
            }
        }
    } else {
        so->fill = so->used;
        for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
            if (entry->key != NULL && entry->key != dummy) {
                set_insert_clean(newtable, newmask, entry->key, entry->hash);
            }
        }
    }

    FT_ATOMIC_STORE_PTR_RELEASE(so->table, newtable);

    if (is_oldtable_malloced)
        free_entries(oldtable, oldsize, SET_IS_SHARED(so));
    return 0;
}

static int
set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
#ifdef Py_GIL_DISABLED
    return set_lookkey_threadsafe(so, key, hash);
#else
    setentry *entry; // unused
    return set_lookkey(so, key, hash, &entry);
#endif
}

#define DISCARD_NOTFOUND 0
#define DISCARD_FOUND 1

static int
set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    setentry *entry;
    PyObject *old_key;
    int status = set_lookkey(so, key, hash, &entry);
    if (status < 0) {
        return -1;
    }
    if (status == SET_LOOKKEY_NO_MATCH) {
        return DISCARD_NOTFOUND;
    }
    assert(status == SET_LOOKKEY_FOUND);
    old_key = entry->key;
    FT_ATOMIC_STORE_SSIZE_RELAXED(entry->hash, -1);
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used - 1);
    FT_ATOMIC_STORE_PTR_RELEASE(entry->key, dummy);
    Py_DECREF(old_key);
    return DISCARD_FOUND;
}

static int
set_add_key(PySetObject *so, PyObject *key)
{
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1) {
        set_unhashable_type(key);
        return -1;
    }
    return set_add_entry(so, key, hash);
}

static int
set_contains_key(PySetObject *so, PyObject *key)
{
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1) {
        set_unhashable_type(key);
        return -1;
    }
    return set_contains_entry(so, key, hash);
}

static int
set_discard_key(PySetObject *so, PyObject *key)
{
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1) {
        set_unhashable_type(key);
        return -1;
    }
    return set_discard_entry(so, key, hash);
}

static void
set_empty_to_minsize(PySetObject *so)
{
    FT_ATOMIC_STORE_PTR_RELEASE(so->table, NULL);
    set_zero_table(so->smalltable, PySet_MINSIZE);
    so->fill = 0;
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, 0);
    FT_ATOMIC_STORE_SSIZE_RELEASE(so->mask, PySet_MINSIZE - 1);
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->hash, -1);
    FT_ATOMIC_STORE_PTR_RELEASE(so->table, so->smalltable);
}

static int
set_clear_internal(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    setentry *entry;
    setentry *table = so->table;
    Py_ssize_t fill = so->fill;
    Py_ssize_t used = so->used;
    Py_ssize_t oldsize = (size_t)so->mask + 1;
    int table_is_malloced = table != so->smalltable;
    setentry small_copy[PySet_MINSIZE];

    assert (PyAnySet_Check(so));
    assert(table != NULL);

    /* This is delicate.  During the process of clearing the set,
     * decrefs can cause the set to mutate.  To avoid fatal confusion
     * (voice of experience), we have to make the set empty before
     * clearing the slots, and never refer to anything via so->ref while
     * clearing.
     */
    if (table_is_malloced)
        set_empty_to_minsize(so);

    else if (fill > 0) {
        /* It's a small table with something that needs to be cleared.
         * Afraid the only safe way is to copy the set entries into
         * another small table first.
         */
        memcpy(small_copy, table, sizeof(small_copy));
        table = small_copy;
        set_empty_to_minsize(so);
    }
    /* else it's a small table that's already empty */

    /* Now we can finally clear things.  If C had refcounts, we could
     * assert that the refcount on table is 1 now, i.e. that this function
     * has unique access to it, so decref side-effects can't alter it.
     */
    for (entry = table; used > 0; entry++) {
        if (entry->key && entry->key != dummy) {
            used--;
            Py_DECREF(entry->key);
        }
    }

    if (table_is_malloced)
        free_entries(table, oldsize, SET_IS_SHARED(so));
    return 0;
}

/*
 * Iterate over a set table.  Use like so:
 *
 *     Py_ssize_t pos;
 *     setentry *entry;
 *     pos = 0;   # important!  pos should not otherwise be changed by you
 *     while (set_next(yourset, &pos, &entry)) {
 *              Refer to borrowed reference in entry->key.
 *     }
 *
 * CAUTION:  In general, it isn't safe to use set_next in a loop that
 * mutates the table.
 */
static int
set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
{
    Py_ssize_t i;
    Py_ssize_t mask;
    setentry *entry;

    assert (PyAnySet_Check(so));
    i = *pos_ptr;
    assert(i >= 0);
    mask = so->mask;
    entry = &so->table[i];
    while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
        i++;
        entry++;
    }
    *pos_ptr = i+1;
    if (i > mask)
        return 0;
    assert(entry != NULL);
    *entry_ptr = entry;
    return 1;
}

static void
set_dealloc(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    setentry *entry;
    Py_ssize_t used = so->used;
    Py_ssize_t oldsize = (size_t)so->mask + 1;

    /* bpo-31095: UnTrack is needed before calling any callbacks */
    PyObject_GC_UnTrack(so);
    FT_CLEAR_WEAKREFS(self, so->weakreflist);

    for (entry = so->table; used > 0; entry++) {
        if (entry->key && entry->key != dummy) {
                used--;
                Py_DECREF(entry->key);
        }
    }
    if (so->table != so->smalltable)
        free_entries(so->table, oldsize, SET_IS_SHARED(so));
    Py_TYPE(so)->tp_free(so);
}

static PyObject *
set_repr_lock_held(PySetObject *so)
{
    PyObject *result=NULL, *keys, *listrepr, *tmp;
    int status = Py_ReprEnter((PyObject*)so);

    if (status != 0) {
        if (status < 0)
            return NULL;
        return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
    }

    /* shortcut for the empty set */
    if (!so->used) {
        Py_ReprLeave((PyObject*)so);
        return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
    }

    // gh-129967: avoid PySequence_List because it might re-lock the object
    // lock or the GIL and allow something to clear the set from underneath us.
    keys = PyList_New(so->used);
    if (keys == NULL) {
        goto done;
    }

    Py_ssize_t pos = 0, idx = 0;
    setentry *entry;
    while (set_next(so, &pos, &entry)) {
        PyList_SET_ITEM(keys, idx++, Py_NewRef(entry->key));
    }

    /* repr(keys)[1:-1] */
    listrepr = PyObject_Repr(keys);
    Py_DECREF(keys);
    if (listrepr == NULL)
        goto done;
    tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
    Py_DECREF(listrepr);
    if (tmp == NULL)
        goto done;
    listrepr = tmp;

    if (!PySet_CheckExact(so))
        result = PyUnicode_FromFormat("%s({%U})",
                                      Py_TYPE(so)->tp_name,
                                      listrepr);
    else
        result = PyUnicode_FromFormat("{%U}", listrepr);
    Py_DECREF(listrepr);
done:
    Py_ReprLeave((PyObject*)so);
    return result;
}

static PyObject *
set_repr(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    PyObject *result;
    Py_BEGIN_CRITICAL_SECTION(so);
    result = set_repr_lock_held(so);
    Py_END_CRITICAL_SECTION();
    return result;
}

static Py_ssize_t
set_len(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    return FT_ATOMIC_LOAD_SSIZE_RELAXED(so->used);
}

static int
set_merge_lock_held(PySetObject *so, PyObject *otherset)
{
    PySetObject *other;
    PyObject *key;
    Py_ssize_t i;
    setentry *so_entry;
    setentry *other_entry;

    assert (PyAnySet_Check(so));
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(otherset);

    other = _PySet_CAST(otherset);
    if (other == so || other->used == 0)
        /* a.update(a) or a.update(set()); nothing to do */
        return 0;
    /* Do one big resize at the start, rather than
     * incrementally resizing as we insert new keys.  Expect
     * that there will be no (or few) overlapping keys.
     */
    if ((so->fill + other->used)*5 >= so->mask*3) {
        if (set_table_resize(so, (so->used + other->used)*2) != 0)
            return -1;
    }
    so_entry = so->table;
    other_entry = other->table;

    /* If our table is empty, and both tables have the same size, and
       there are no dummies to eliminate, then just copy the pointers. */
    if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
        for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
            key = other_entry->key;
            if (key != NULL) {
                assert(so_entry->key == NULL);
                FT_ATOMIC_STORE_SSIZE_RELAXED(so_entry->hash, other_entry->hash);
                FT_ATOMIC_STORE_PTR_RELEASE(so_entry->key, Py_NewRef(key));
            }
        }
        so->fill = other->fill;
        FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, other->used);
        return 0;
    }

    /* If our table is empty, we can use set_insert_clean() */
    if (so->fill == 0) {
        setentry *newtable = so->table;
        size_t newmask = (size_t)so->mask;
        so->fill = other->used;
        FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, other->used);
        for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
            key = other_entry->key;
            if (key != NULL && key != dummy) {
                set_insert_clean(newtable, newmask, Py_NewRef(key),
                                 other_entry->hash);
            }
        }
        return 0;
    }

    /* We can't assure there are no duplicates, so do normal insertions */
    for (i = 0; i <= other->mask; i++) {
        other_entry = &other->table[i];
        key = other_entry->key;
        if (key != NULL && key != dummy) {
            if (set_add_entry(so, key, other_entry->hash))
                return -1;
        }
    }
    return 0;
}

/*[clinic input]
@critical_section
set.pop
    so: setobject

Remove and return an arbitrary set element.

Raises KeyError if the set is empty.
[clinic start generated code]*/

static PyObject *
set_pop_impl(PySetObject *so)
/*[clinic end generated code: output=4d65180f1271871b input=9296c84921125060]*/
{
    /* Make sure the search finger is in bounds */
    setentry *entry = so->table + (so->finger & so->mask);
    setentry *limit = so->table + so->mask;
    PyObject *key;

    if (so->used == 0) {
        PyErr_SetString(PyExc_KeyError, "pop from an empty set");
        return NULL;
    }
    while (entry->key == NULL || entry->key==dummy) {
        entry++;
        if (entry > limit)
            entry = so->table;
    }
    FT_ATOMIC_STORE_SSIZE_RELAXED(entry->hash, -1);
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used - 1);
    key = entry->key;
    FT_ATOMIC_STORE_PTR_RELEASE(entry->key, dummy);
    so->finger = entry - so->table + 1;   /* next place to start */
    return key;
}

static int
set_traverse(PyObject *self, visitproc visit, void *arg)
{
    PySetObject *so = _PySet_CAST(self);
    Py_ssize_t pos = 0;
    setentry *entry;

    while (set_next(so, &pos, &entry))
        Py_VISIT(entry->key);
    return 0;
}

/* Work to increase the bit dispersion for closely spaced hash values.
   This is important because some use cases have many combinations of a
   small number of elements with nearby hashes so that many distinct
   combinations collapse to only a handful of distinct hash values. */

static Py_uhash_t
_shuffle_bits(Py_uhash_t h)
{
    return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
}

/* Most of the constants in this hash algorithm are randomly chosen
   large primes with "interesting bit patterns" and that passed tests
   for good collision statistics on a variety of problematic datasets
   including powersets and graph structures (such as David Eppstein's
   graph recipes in Lib/test/test_set.py).

   This hash algorithm can be used on either a frozenset or a set.
   When it is used on a set, it computes the hash value of the equivalent
   frozenset without creating a new frozenset object.

   If you update this code, update also frozendict_hash() which copied this
   code. */

static Py_hash_t
frozenset_hash_impl(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    Py_uhash_t hash = 0;
    setentry *entry;

    /* Xor-in shuffled bits from every entry's hash field because xor is
       commutative and a frozenset hash should be independent of order.

       For speed, include null entries and dummy entries and then
       subtract out their effect afterwards so that the final hash
       depends only on active entries.  This allows the code to be
       vectorized by the compiler and it saves the unpredictable
       branches that would arise when trying to exclude null and dummy
       entries on every iteration. */

    for (entry = so->table; entry <= &so->table[so->mask]; entry++)
        hash ^= _shuffle_bits(entry->hash);

    /* Remove the effect of an odd number of NULL entries */
    if ((so->mask + 1 - so->fill) & 1)
        hash ^= _shuffle_bits(0);

    /* Remove the effect of an odd number of dummy entries */
    if ((so->fill - so->used) & 1)
        hash ^= _shuffle_bits(-1);

    /* Factor in the number of active entries */
    hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;

    /* Disperse patterns arising in nested frozensets */
    hash ^= (hash >> 11) ^ (hash >> 25);
    hash = hash * 69069U + 907133923UL;

    /* -1 is reserved as an error code */
    if (hash == (Py_uhash_t)-1)
        hash = 590923713UL;

    return (Py_hash_t)hash;
}

static Py_hash_t
frozenset_hash(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    Py_uhash_t hash;

    if (FT_ATOMIC_LOAD_SSIZE_RELAXED(so->hash) != -1) {
        return FT_ATOMIC_LOAD_SSIZE_ACQUIRE(so->hash);
    }

    hash = frozenset_hash_impl(self);
    FT_ATOMIC_STORE_SSIZE_RELEASE(so->hash, hash);
    return hash;
}

/***** Set iterator type ***********************************************/

typedef struct {
    PyObject_HEAD
    PySetObject *si_set; /* Set to NULL when iterator is exhausted */
    Py_ssize_t si_used;
    Py_ssize_t si_pos;
    Py_ssize_t len;
} setiterobject;

static void
setiter_dealloc(PyObject *self)
{
    setiterobject *si = (setiterobject*)self;
    /* bpo-31095: UnTrack is needed before calling any callbacks */
    _PyObject_GC_UNTRACK(si);
    Py_XDECREF(si->si_set);
    PyObject_GC_Del(si);
}

static int
setiter_traverse(PyObject *self, visitproc visit, void *arg)
{
    setiterobject *si = (setiterobject*)self;
    Py_VISIT(si->si_set);
    return 0;
}

static PyObject *
setiter_len(PyObject *op, PyObject *Py_UNUSED(ignored))
{
    setiterobject *si = (setiterobject*)op;
    Py_ssize_t len = 0;
    if (si->si_set != NULL && si->si_used == si->si_set->used)
        len = si->len;
    return PyLong_FromSsize_t(len);
}

PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");

static PyObject *
setiter_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
{
    setiterobject *si = (setiterobject*)op;

    /* copy the iterator state */
    setiterobject tmp = *si;
    Py_XINCREF(tmp.si_set);

    /* iterate the temporary into a list */
    PyObject *list = PySequence_List((PyObject*)&tmp);
    Py_XDECREF(tmp.si_set);
    if (list == NULL) {
        return NULL;
    }
    return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list);
}

PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");

static PyMethodDef setiter_methods[] = {
    {"__length_hint__", setiter_len, METH_NOARGS, length_hint_doc},
    {"__reduce__", setiter_reduce, METH_NOARGS, reduce_doc},
    {NULL,              NULL}           /* sentinel */
};

static PyObject *setiter_iternext(PyObject *self)
{
    setiterobject *si = (setiterobject*)self;
    PyObject *key = NULL;
    Py_ssize_t i, mask;
    setentry *entry;
    PySetObject *so = si->si_set;

    if (so == NULL)
        return NULL;
    assert (PyAnySet_Check(so));

    Py_ssize_t so_used = FT_ATOMIC_LOAD_SSIZE_RELAXED(so->used);
    Py_ssize_t si_used = FT_ATOMIC_LOAD_SSIZE_RELAXED(si->si_used);
    if (si_used != so_used) {
        PyErr_SetString(PyExc_RuntimeError,
                        "Set changed size during iteration");
        si->si_used = -1; /* Make this state sticky */
        return NULL;
    }

    Py_BEGIN_CRITICAL_SECTION(so);
    i = si->si_pos;
    assert(i>=0);
    entry = so->table;
    mask = so->mask;
    while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy)) {
        i++;
    }
    if (i <= mask) {
        key = Py_NewRef(entry[i].key);
    }
    Py_END_CRITICAL_SECTION();
    si->si_pos = i+1;
    if (key == NULL) {
        si->si_set = NULL;
        Py_DECREF(so);
        return NULL;
    }
    si->len--;
    return key;
}

PyTypeObject PySetIter_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "set_iterator",                             /* tp_name */
    sizeof(setiterobject),                      /* tp_basicsize */
    0,                                          /* tp_itemsize */
    /* methods */
    setiter_dealloc,                            /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_as_async */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
    0,                                          /* tp_doc */
    setiter_traverse,                           /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    PyObject_SelfIter,                          /* tp_iter */
    setiter_iternext,                           /* tp_iternext */
    setiter_methods,                            /* tp_methods */
    0,
};

static PyObject *
set_iter(PyObject *so)
{
    Py_ssize_t size = set_len(so);
    setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
    if (si == NULL)
        return NULL;
    si->si_set = (PySetObject*)Py_NewRef(so);
    si->si_used = size;
    si->si_pos = 0;
    si->len = size;
    _PyObject_GC_TRACK(si);
    return (PyObject *)si;
}

static int
set_update_dict_lock_held(PySetObject *so, PyObject *other)
{
    assert(PyAnyDict_CheckExact(other));

    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
#ifdef Py_DEBUG
    if (!PyFrozenDict_CheckExact(other)) {
        _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);
    }
#endif

    /* Do one big resize at the start, rather than
    * incrementally resizing as we insert new keys.  Expect
    * that there will be no (or few) overlapping keys.
    */
    Py_ssize_t dictsize = PyDict_GET_SIZE(other);
    if ((so->fill + dictsize)*5 >= so->mask*3) {
        if (set_table_resize(so, (so->used + dictsize)*2) != 0) {
            return -1;
        }
    }

    Py_ssize_t pos = 0;
    PyObject *key;
    PyObject *value;
    Py_hash_t hash;
    while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
        if (set_add_entry(so, key, hash)) {
            return -1;
        }
    }
    return 0;
}

static int
set_update_iterable_lock_held(PySetObject *so, PyObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);

    PyObject *it = PyObject_GetIter(other);
    if (it == NULL) {
        return -1;
    }

    PyObject *key;
    while ((key = PyIter_Next(it)) != NULL) {
        if (set_add_key(so, key)) {
            Py_DECREF(it);
            Py_DECREF(key);
            return -1;
        }
        Py_DECREF(key);
    }
    Py_DECREF(it);
    if (PyErr_Occurred())
        return -1;
    return 0;
}

static int
set_update_lock_held(PySetObject *so, PyObject *other)
{
    if (PyAnySet_Check(other)) {
        return set_merge_lock_held(so, other);
    }
    else if (PyAnyDict_CheckExact(other)) {
        return set_update_dict_lock_held(so, other);
    }
    return set_update_iterable_lock_held(so, other);
}

// set_update for a `so` that is only visible to the current thread
static int
set_update_local(PySetObject *so, PyObject *other)
{
    assert(Py_REFCNT(so) == 1);
    if (PyAnySet_Check(other)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(other);
        rv = set_merge_lock_held(so, other);
        Py_END_CRITICAL_SECTION();
        return rv;
    }
    else if (PyDict_CheckExact(other)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(other);
        rv = set_update_dict_lock_held(so, other);
        Py_END_CRITICAL_SECTION();
        return rv;
    }
    else if (PyFrozenDict_CheckExact(other)) {
        return set_update_dict_lock_held(so, other);
    }
    return set_update_iterable_lock_held(so, other);
}

static int
set_update_internal(PySetObject *so, PyObject *other)
{
    if (PyAnySet_Check(other)) {
        if (Py_Is((PyObject *)so, other)) {
            return 0;
        }
        int rv;
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_merge_lock_held(so, other);
        Py_END_CRITICAL_SECTION2();
        return rv;
    }
    else if (PyDict_CheckExact(other)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_update_dict_lock_held(so, other);
        Py_END_CRITICAL_SECTION2();
        return rv;
    }
    else if (PyFrozenDict_CheckExact(other)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(so);
        rv = set_update_dict_lock_held(so, other);
        Py_END_CRITICAL_SECTION();
        return rv;
    }
    else {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(so);
        rv = set_update_iterable_lock_held(so, other);
        Py_END_CRITICAL_SECTION();
        return rv;
    }
}

/*[clinic input]
set.update
    so: setobject
    *others: array

Update the set, adding elements from all others.
[clinic start generated code]*/

static PyObject *
set_update_impl(PySetObject *so, PyObject * const *others,
                Py_ssize_t others_length)
/*[clinic end generated code: output=017c781c992d5c23 input=ed5d78885b076636]*/
{
    Py_ssize_t i;

    for (i = 0; i < others_length; i++) {
        PyObject *other = others[i];
        if (set_update_internal(so, other))
            return NULL;
    }
    Py_RETURN_NONE;
}

/* XXX Todo:
   If aligned memory allocations become available, make the
   set object 64 byte aligned so that most of the fields
   can be retrieved or updated in a single cache line.
*/

// Build a set/frozenset left GC-untracked; the caller must _PyObject_GC_TRACK()
// it once fully built, so a half-built set is never exposed during filling.
static PyObject *
make_new_set_untracked(PyTypeObject *type, PyObject *iterable)
{
    assert(PyType_Check(type));
    PySetObject *so;

    so = (PySetObject *)_PyType_AllocNoTrack(type, 0);
    if (so == NULL)
        return NULL;

    so->fill = 0;
    so->used = 0;
    so->mask = PySet_MINSIZE - 1;
    so->table = so->smalltable;
    so->hash = -1;
    so->finger = 0;
    so->weakreflist = NULL;

    if (iterable != NULL) {
        if (set_update_local(so, iterable)) {
            Py_DECREF(so);
            return NULL;
        }
    }

    return (PyObject *)so;
}

static PyObject *
make_new_set(PyTypeObject *type, PyObject *iterable)
{
    PyObject *so = make_new_set_untracked(type, iterable);
    if (so != NULL) {
        _PyObject_GC_TRACK(so);
    }
    return so;
}

static PyObject *
make_new_set_basetype_untracked(PyTypeObject *type, PyObject *iterable)
{
    if (type != &PySet_Type && type != &PyFrozenSet_Type) {
        if (PyType_IsSubtype(type, &PySet_Type))
            type = &PySet_Type;
        else
            type = &PyFrozenSet_Type;
    }
    return make_new_set_untracked(type, iterable);
}

static PyObject *
make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
{
    PyObject *so = make_new_set_basetype_untracked(type, iterable);
    if (so != NULL) {
        _PyObject_GC_TRACK(so);
    }
    return so;
}

// gh-140232: check whether a frozenset can be untracked from the GC
static void
_PyFrozenSet_MaybeUntrack(PyObject *op)
{
    assert(op != NULL);
    // subclasses of a frozenset can generate reference cycles, so do not untrack
    if (!PyFrozenSet_CheckExact(op)) {
        return;
    }
    // if no elements of a frozenset are tracked by the GC, we untrack the object
    Py_ssize_t pos = 0;
    setentry *entry;
    while (set_next((PySetObject *)op, &pos, &entry)) {
        if (_PyObject_GC_MAY_BE_TRACKED(entry->key)) {
            return;
        }
    }
    _PyObject_GC_UNTRACK(op);
}

static PyObject *
make_new_frozenset(PyTypeObject *type, PyObject *iterable)
{
    if (type != &PyFrozenSet_Type) {
        return make_new_set(type, iterable);
    }

    if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
        /* frozenset(f) is idempotent */
        return Py_NewRef(iterable);
    }
    PyObject *obj = make_new_set(type, iterable);
    if (obj != NULL) {
        _PyFrozenSet_MaybeUntrack(obj);
    }
    return obj;
}

static PyObject *
frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *iterable = NULL;

    if ((type == &PyFrozenSet_Type ||
         type->tp_init == PyFrozenSet_Type.tp_init) &&
        !_PyArg_NoKeywords("frozenset", kwds)) {
        return NULL;
    }

    if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
        return NULL;
    }

    return make_new_frozenset(type, iterable);
}

static PyObject *
frozenset_vectorcall(PyObject *type, PyObject * const*args,
                     size_t nargsf, PyObject *kwnames)
{
    if (!_PyArg_NoKwnames("frozenset", kwnames)) {
        return NULL;
    }

    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
    if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
        return NULL;
    }

    PyObject *iterable = (nargs ? args[0] : NULL);
    return make_new_frozenset(_PyType_CAST(type), iterable);
}

static PyObject *
set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    return make_new_set(type, NULL);
}

#ifdef Py_GIL_DISABLED
static void
copy_small_table(setentry *dest, setentry *src)
{
    for (Py_ssize_t i = 0; i < PySet_MINSIZE; i++) {
        _Py_atomic_store_ptr_release(&dest[i].key, src[i].key);
        _Py_atomic_store_ssize_relaxed(&dest[i].hash, src[i].hash);
    }
}
#endif

/* set_swap_bodies() switches the contents of any two sets by moving their
   internal data pointers and, if needed, copying the internal smalltables.
   Semantically equivalent to:

     t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t

   The function always succeeds and it leaves both objects in a stable state.
   Useful for operations that update in-place (by allowing an intermediate
   result to be swapped into one of the original inputs).
*/

static void
set_swap_bodies(PySetObject *a, PySetObject *b)
{
    Py_ssize_t t;
    setentry *u;
    setentry tab[PySet_MINSIZE];
    Py_hash_t h;

    setentry *a_table = a->table;
    setentry *b_table = b->table;
    FT_ATOMIC_STORE_PTR_RELEASE(a->table, NULL);
    FT_ATOMIC_STORE_PTR_RELEASE(b->table, NULL);

    t = a->fill;     a->fill   = b->fill;        b->fill  = t;
    t = a->used;
    FT_ATOMIC_STORE_SSIZE_RELAXED(a->used, b->used);
    FT_ATOMIC_STORE_SSIZE_RELAXED(b->used, t);
    t = a->mask;
    FT_ATOMIC_STORE_SSIZE_RELEASE(a->mask, b->mask);
    FT_ATOMIC_STORE_SSIZE_RELEASE(b->mask, t);

    u = a_table;
    if (a_table == a->smalltable)
        u = b->smalltable;
    a_table  = b_table;
    if (b_table == b->smalltable)
        a_table = a->smalltable;
    b_table = u;

    if (a_table == a->smalltable || b_table == b->smalltable) {
        memcpy(tab, a->smalltable, sizeof(tab));
#ifndef Py_GIL_DISABLED
        memcpy(a->smalltable, b->smalltable, sizeof(tab));
        memcpy(b->smalltable, tab, sizeof(tab));
#else
        copy_small_table(a->smalltable, b->smalltable);
        copy_small_table(b->smalltable, tab);
#endif
    }

    if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type)  &&
        PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
        h = FT_ATOMIC_LOAD_SSIZE_RELAXED(a->hash);
        FT_ATOMIC_STORE_SSIZE_RELAXED(a->hash, FT_ATOMIC_LOAD_SSIZE_RELAXED(b->hash));
        FT_ATOMIC_STORE_SSIZE_RELAXED(b->hash, h);
    } else {
        FT_ATOMIC_STORE_SSIZE_RELAXED(a->hash, -1);
        FT_ATOMIC_STORE_SSIZE_RELAXED(b->hash, -1);
    }
    if (!SET_IS_SHARED(b) && SET_IS_SHARED(a)) {
        SET_MARK_SHARED(b);
    }
    if (!SET_IS_SHARED(a) && SET_IS_SHARED(b)) {
        SET_MARK_SHARED(a);
    }
    FT_ATOMIC_STORE_PTR_RELEASE(a->table, a_table);
    FT_ATOMIC_STORE_PTR_RELEASE(b->table, b_table);
}

PyObject *
_PySet_Freeze(PyObject *set)
{
    assert(set != NULL);
    assert(PySet_CheckExact(set));
    assert(_PyObject_IsUniquelyReferenced(set));
    set->ob_type = &PyFrozenSet_Type;
    return Py_NewRef(set);
}

static PyObject *
set_copy_untracked_lock_held(PySetObject *so)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    PyObject *copy = make_new_set_basetype_untracked(Py_TYPE(so), NULL);
    if (copy == NULL) {
        return NULL;
    }
    if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
        Py_DECREF(copy);
        return NULL;
    }
    return copy;
}

/*[clinic input]
@critical_section
set.copy
    so: setobject

Return a shallow copy of a set.
[clinic start generated code]*/

static PyObject *
set_copy_impl(PySetObject *so)
/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
{
    PyObject *copy = set_copy_untracked_lock_held(so);
    if (copy != NULL) {
        _PyObject_GC_TRACK(copy);
    }
    return copy;
}

/*[clinic input]
@critical_section
frozenset.copy
    so: setobject

Return a shallow copy of a set.
[clinic start generated code]*/

static PyObject *
frozenset_copy_impl(PySetObject *so)
/*[clinic end generated code: output=b356263526af9e70 input=fbf5bef131268dd7]*/
{
    if (PyFrozenSet_CheckExact(so)) {
        return Py_NewRef(so);
    }
    return set_copy_impl(so);
}

/*[clinic input]
@critical_section
set.clear
    so: setobject

Remove all elements from this set.
[clinic start generated code]*/

static PyObject *
set_clear_impl(PySetObject *so)
/*[clinic end generated code: output=4e71d5a83904161a input=c6f831b366111950]*/
{
    set_clear_internal((PyObject*)so);
    Py_RETURN_NONE;
}

/*[clinic input]
set.union
    so: setobject
    *others: array

Return a new set with elements from the set and all others.
[clinic start generated code]*/

static PyObject *
set_union_impl(PySetObject *so, PyObject * const *others,
               Py_ssize_t others_length)
/*[clinic end generated code: output=b1bfa3d74065f27e input=55a2e81db6347a4f]*/
{
    PySetObject *result;
    PyObject *other;
    Py_ssize_t i;

    result = (PySetObject *)make_new_set_basetype_untracked(Py_TYPE(so),
                                                            (PyObject *)so);
    if (result == NULL)
        return NULL;

    for (i = 0; i < others_length; i++) {
        other = others[i];
        if ((PyObject *)so == other)
            continue;
        if (set_update_local(result, other)) {
            Py_DECREF(result);
            return NULL;
        }
    }
    _PyObject_GC_TRACK(result);
    return (PyObject *)result;
}

static PyObject *
set_or(PyObject *self, PyObject *other)
{
    PySetObject *result;

    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;

    result = (PySetObject *)set_copy(self, NULL);
    if (result == NULL) {
        return NULL;
    }
    if (Py_Is(self, other)) {
        return (PyObject *)result;
    }
    if (set_update_local(result, other)) {
        Py_DECREF(result);
        return NULL;
    }
    return (PyObject *)result;
}

static PyObject *
set_ior(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    if (set_update_internal(so, other)) {
        return NULL;
    }
    return Py_NewRef(so);
}

static PyObject *
set_intersection(PySetObject *so, PyObject *other)
{
    PySetObject *result;
    PyObject *key, *it, *tmp;
    Py_hash_t hash;
    int rv;

    if ((PyObject *)so == other)
        return set_copy_impl(so);

    result = (PySetObject *)make_new_set_basetype_untracked(Py_TYPE(so), NULL);
    if (result == NULL)
        return NULL;

    if (PyAnySet_Check(other)) {
        Py_ssize_t pos = 0;
        setentry *entry;

        if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
            tmp = (PyObject *)so;
            so = (PySetObject *)other;
            other = tmp;
        }

        while (set_next((PySetObject *)other, &pos, &entry)) {
            key = entry->key;
            hash = entry->hash;
            Py_INCREF(key);
            rv = set_contains_entry(so, key, hash);
            if (rv < 0) {
                Py_DECREF(result);
                Py_DECREF(key);
                return NULL;
            }
            if (rv) {
                if (set_add_entry(result, key, hash)) {
                    Py_DECREF(result);
                    Py_DECREF(key);
                    return NULL;
                }
            }
            Py_DECREF(key);
        }
        _PyObject_GC_TRACK(result);
        return (PyObject *)result;
    }

    it = PyObject_GetIter(other);
    if (it == NULL) {
        Py_DECREF(result);
        return NULL;
    }

    while ((key = PyIter_Next(it)) != NULL) {
        hash = PyObject_Hash(key);
        if (hash == -1)
            goto error;
        rv = set_contains_entry(so, key, hash);
        if (rv < 0)
            goto error;
        if (rv) {
            if (set_add_entry(result, key, hash))
                goto error;
            if (PySet_GET_SIZE(result) >= PySet_GET_SIZE(so)) {
                Py_DECREF(key);
                break;
            }
        }
        Py_DECREF(key);
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        Py_DECREF(result);
        return NULL;
    }
    _PyObject_GC_TRACK(result);
    return (PyObject *)result;
  error:
    Py_DECREF(it);
    Py_DECREF(result);
    Py_DECREF(key);
    return NULL;
}

/*[clinic input]
set.intersection as set_intersection_multi
    so: setobject
    *others: array

Return a new set with elements common to the set and all others.
[clinic start generated code]*/

static PyObject *
set_intersection_multi_impl(PySetObject *so, PyObject * const *others,
                            Py_ssize_t others_length)
/*[clinic end generated code: output=db9ff9f875132b6b input=36c7b615694cadae]*/
{
    Py_ssize_t i;

    if (others_length == 0) {
        return set_copy((PyObject *)so, NULL);
    }

    PyObject *result = Py_NewRef(so);
    for (i = 0; i < others_length; i++) {
        PyObject *other = others[i];
        PyObject *newresult;
        Py_BEGIN_CRITICAL_SECTION2(result, other);
        newresult = set_intersection((PySetObject *)result, other);
        Py_END_CRITICAL_SECTION2();
        if (newresult == NULL) {
            Py_DECREF(result);
            return NULL;
        }
        Py_SETREF(result, newresult);
    }
    return result;
}

static PyObject *
set_intersection_update(PySetObject *so, PyObject *other)
{
    PyObject *tmp;

    tmp = set_intersection(so, other);
    if (tmp == NULL)
        return NULL;
    set_swap_bodies(so, (PySetObject *)tmp);
    Py_DECREF(tmp);
    Py_RETURN_NONE;
}

/*[clinic input]
set.intersection_update as set_intersection_update_multi
    so: setobject
    *others: array

Update the set, keeping only elements found in it and all others.
[clinic start generated code]*/

static PyObject *
set_intersection_update_multi_impl(PySetObject *so, PyObject * const *others,
                                   Py_ssize_t others_length)
/*[clinic end generated code: output=d768b5584675b48d input=782e422fc370e4fc]*/
{
    PyObject *tmp;

    tmp = set_intersection_multi_impl(so, others, others_length);
    if (tmp == NULL)
        return NULL;
    Py_BEGIN_CRITICAL_SECTION(so);
    set_swap_bodies(so, (PySetObject *)tmp);
    Py_END_CRITICAL_SECTION();
    Py_DECREF(tmp);
    Py_RETURN_NONE;
}

static PyObject *
set_and(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    PyObject *rv;
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    rv = set_intersection(so, other);
    Py_END_CRITICAL_SECTION2();

    return rv;
}

static PyObject *
set_iand(PyObject *self, PyObject *other)
{
    PyObject *result;

    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    Py_BEGIN_CRITICAL_SECTION2(so, other);
    result = set_intersection_update(so, other);
    Py_END_CRITICAL_SECTION2();

    if (result == NULL)
        return NULL;
    Py_DECREF(result);
    return Py_NewRef(so);
}

/*[clinic input]
@critical_section so other
set.isdisjoint
    so: setobject
    other: object
    /

Return True if two sets have a null intersection.
[clinic start generated code]*/

static PyObject *
set_isdisjoint_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=273493f2d57c565e input=32f8dcab5e0fc7d6]*/
{
    PyObject *key, *it, *tmp;
    int rv;

    if ((PyObject *)so == other) {
        if (PySet_GET_SIZE(so) == 0)
            Py_RETURN_TRUE;
        else
            Py_RETURN_FALSE;
    }

    if (PyAnySet_CheckExact(other)) {
        Py_ssize_t pos = 0;
        setentry *entry;

        if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
            tmp = (PyObject *)so;
            so = (PySetObject *)other;
            other = tmp;
        }
        while (set_next((PySetObject *)other, &pos, &entry)) {
            PyObject *key = entry->key;
            Py_INCREF(key);
            rv = set_contains_entry(so, key, entry->hash);
            Py_DECREF(key);
            if (rv < 0) {
                return NULL;
            }
            if (rv) {
                Py_RETURN_FALSE;
            }
        }
        Py_RETURN_TRUE;
    }

    it = PyObject_GetIter(other);
    if (it == NULL)
        return NULL;

    while ((key = PyIter_Next(it)) != NULL) {
        rv = set_contains_key(so, key);
        Py_DECREF(key);
        if (rv < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (rv) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred())
        return NULL;
    Py_RETURN_TRUE;
}

static int
set_difference_update_internal(PySetObject *so, PyObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);

    if ((PyObject *)so == other)
        return set_clear_internal((PyObject*)so);

    if (PyAnySet_Check(other)) {
        setentry *entry;
        Py_ssize_t pos = 0;

        /* Optimization:  When the other set is more than 8 times
           larger than the base set, replace the other set with
           intersection of the two sets.
        */
        if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
            other = set_intersection(so, other);
            if (other == NULL)
                return -1;
        } else {
            Py_INCREF(other);
        }

        while (set_next((PySetObject *)other, &pos, &entry)) {
            PyObject *key = entry->key;
            Py_INCREF(key);
            if (set_discard_entry(so, key, entry->hash) < 0) {
                Py_DECREF(other);
                Py_DECREF(key);
                return -1;
            }
            Py_DECREF(key);
        }

        Py_DECREF(other);
    } else {
        PyObject *key, *it;
        it = PyObject_GetIter(other);
        if (it == NULL)
            return -1;

        while ((key = PyIter_Next(it)) != NULL) {
            if (set_discard_key(so, key) < 0) {
                Py_DECREF(it);
                Py_DECREF(key);
                return -1;
            }
            Py_DECREF(key);
        }
        Py_DECREF(it);
        if (PyErr_Occurred())
            return -1;
    }
    /* If more than 1/4th are dummies, then resize them away. */
    if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
        return 0;
    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
}

/*[clinic input]
set.difference_update
    so: setobject
    *others: array

Update the set, removing elements found in others.
[clinic start generated code]*/

static PyObject *
set_difference_update_impl(PySetObject *so, PyObject * const *others,
                           Py_ssize_t others_length)
/*[clinic end generated code: output=04a22179b322cfe6 input=93ac28ba5b233696]*/
{
    Py_ssize_t i;

    for (i = 0; i < others_length; i++) {
        PyObject *other = others[i];
        int rv;
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_difference_update_internal(so, other);
        Py_END_CRITICAL_SECTION2();
        if (rv) {
            return NULL;
        }
    }
    Py_RETURN_NONE;
}

static PyObject *
set_copy_and_difference_untracked(PySetObject *so, PyObject *other)
{
    PyObject *result;

    result = set_copy_untracked_lock_held(so);
    if (result == NULL)
        return NULL;
    if (set_difference_update_internal((PySetObject *) result, other) == 0)
        return result;
    Py_DECREF(result);
    return NULL;
}

static PyObject *
set_difference_untracked(PySetObject *so, PyObject *other)
{
    PyObject *result;
    PyObject *key;
    Py_hash_t hash;
    setentry *entry;
    Py_ssize_t pos = 0, other_size;
    int rv;

    if (PyAnySet_Check(other)) {
        other_size = PySet_GET_SIZE(other);
    }
    else if (PyAnyDict_CheckExact(other)) {
        other_size = PyDict_GET_SIZE(other);
    }
    else {
        return set_copy_and_difference_untracked(so, other);
    }

    /* If len(so) much more than len(other), it's more efficient to simply copy
     * so and then iterate other looking for common elements. */
    if ((PySet_GET_SIZE(so) >> 2) > other_size) {
        return set_copy_and_difference_untracked(so, other);
    }

    result = make_new_set_basetype_untracked(Py_TYPE(so), NULL);
    if (result == NULL)
        return NULL;

    if (PyAnyDict_CheckExact(other)) {
        while (set_next(so, &pos, &entry)) {
            key = entry->key;
            hash = entry->hash;
            Py_INCREF(key);
            rv = _PyDict_Contains_KnownHash(other, key, hash);
            if (rv < 0) {
                Py_DECREF(result);
                Py_DECREF(key);
                return NULL;
            }
            if (!rv) {
                if (set_add_entry((PySetObject *)result, key, hash)) {
                    Py_DECREF(result);
                    Py_DECREF(key);
                    return NULL;
                }
            }
            Py_DECREF(key);
        }
        return result;
    }

    /* Iterate over so, checking for common elements in other. */
    while (set_next(so, &pos, &entry)) {
        key = entry->key;
        hash = entry->hash;
        Py_INCREF(key);
        rv = set_contains_entry((PySetObject *)other, key, hash);
        if (rv < 0) {
            Py_DECREF(result);
            Py_DECREF(key);
            return NULL;
        }
        if (!rv) {
            if (set_add_entry((PySetObject *)result, key, hash)) {
                Py_DECREF(result);
                Py_DECREF(key);
                return NULL;
            }
        }
        Py_DECREF(key);
    }
    return result;
}

/*[clinic input]
@permit_long_summary
set.difference as set_difference_multi
    so: setobject
    *others: array

Return a new set with elements in the set that are not in the others.
[clinic start generated code]*/

static PyObject *
set_difference_multi_impl(PySetObject *so, PyObject * const *others,
                          Py_ssize_t others_length)
/*[clinic end generated code: output=b0d33fb05d5477a7 input=e0fbedbf79d91d4e]*/
{
    Py_ssize_t i;
    PyObject *result, *other;

    if (others_length == 0) {
        return set_copy((PyObject *)so, NULL);
    }

    other = others[0];
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    result = set_difference_untracked(so, other);
    Py_END_CRITICAL_SECTION2();
    if (result == NULL)
        return NULL;

    for (i = 1; i < others_length; i++) {
        other = others[i];
        int rv;
        Py_BEGIN_CRITICAL_SECTION(other);
        rv = set_difference_update_internal((PySetObject *)result, other);
        Py_END_CRITICAL_SECTION();
        if (rv) {
            Py_DECREF(result);
            return NULL;
        }
    }
    _PyObject_GC_TRACK(result);
    return result;
}

static PyObject *
set_sub(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    PyObject *rv;
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    rv = set_difference_untracked(so, other);
    Py_END_CRITICAL_SECTION2();
    if (rv != NULL) {
        _PyObject_GC_TRACK(rv);
    }
    return rv;
}

static PyObject *
set_isub(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    int rv;
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    rv = set_difference_update_internal(so, other);
    Py_END_CRITICAL_SECTION2();
    if (rv < 0) {
        return NULL;
    }
    return Py_NewRef(so);
}

static int
set_symmetric_difference_update_dict(PySetObject *so, PyObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
#ifdef Py_DEBUG
    if (!PyFrozenDict_CheckExact(other)) {
        _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);
    }
#endif

    Py_ssize_t pos = 0;
    PyObject *key, *value;
    Py_hash_t hash;
    while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
        Py_INCREF(key);
        int rv = set_discard_entry(so, key, hash);
        if (rv < 0) {
            Py_DECREF(key);
            return -1;
        }
        if (rv == DISCARD_NOTFOUND) {
            if (set_add_entry(so, key, hash)) {
                Py_DECREF(key);
                return -1;
            }
        }
        Py_DECREF(key);
    }
    return 0;
}

static int
set_symmetric_difference_update_set(PySetObject *so, PySetObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);

    Py_ssize_t pos = 0;
    setentry *entry;
    while (set_next(other, &pos, &entry)) {
        PyObject *key = Py_NewRef(entry->key);
        Py_hash_t hash = entry->hash;
        int rv = set_discard_entry(so, key, hash);
        if (rv < 0) {
            Py_DECREF(key);
            return -1;
        }
        if (rv == DISCARD_NOTFOUND) {
            if (set_add_entry(so, key, hash)) {
                Py_DECREF(key);
                return -1;
            }
        }
        Py_DECREF(key);
    }
    return 0;
}

/*[clinic input]
@permit_long_summary
set.symmetric_difference_update
    so: setobject
    other: object
    /

Update the set, keeping only elements found in either set, but not in both.
[clinic start generated code]*/

static PyObject *
set_symmetric_difference_update_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=79f80b4ee5da66c1 input=86a3dddac9bfb15e]*/
{
    if (Py_Is((PyObject *)so, other)) {
        return set_clear((PyObject *)so, NULL);
    }

    int rv;
    if (PyDict_CheckExact(other)) {
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_symmetric_difference_update_dict(so, other);
        Py_END_CRITICAL_SECTION2();
    }
    else if (PyFrozenDict_CheckExact(other)) {
        Py_BEGIN_CRITICAL_SECTION(so);
        rv = set_symmetric_difference_update_dict(so, other);
        Py_END_CRITICAL_SECTION();
    }
    else if (PyAnySet_Check(other)) {
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_symmetric_difference_update_set(so, (PySetObject *)other);
        Py_END_CRITICAL_SECTION2();
    }
    else {
        PySetObject *otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
        if (otherset == NULL) {
            return NULL;
        }

        Py_BEGIN_CRITICAL_SECTION(so);
        rv = set_symmetric_difference_update_set(so, otherset);
        Py_END_CRITICAL_SECTION();

        Py_DECREF(otherset);
    }
    if (rv < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
@permit_long_summary
@critical_section so other
set.symmetric_difference
    so: setobject
    other: object
    /

Return a new set with elements in either the set or other but not both.
[clinic start generated code]*/

static PyObject *
set_symmetric_difference_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=270ee0b5d42b0797 input=8c29b0be90d47feb]*/
{
    PySetObject *result =
        (PySetObject *)make_new_set_basetype_untracked(Py_TYPE(so), NULL);
    if (result == NULL) {
        return NULL;
    }
    if (set_update_lock_held(result, other) < 0) {
        Py_DECREF(result);
        return NULL;
    }
    if (set_symmetric_difference_update_set(result, so) < 0) {
        Py_DECREF(result);
        return NULL;
    }
    _PyObject_GC_TRACK(result);
    return (PyObject *)result;
}

static PyObject *
set_xor(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);
    return set_symmetric_difference((PyObject*)so, other);
}

static PyObject *
set_ixor(PyObject *self, PyObject *other)
{
    PyObject *result;

    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    result = set_symmetric_difference_update((PyObject*)so, other);
    if (result == NULL)
        return NULL;
    Py_DECREF(result);
    return Py_NewRef(so);
}

/*[clinic input]
@critical_section so other
set.issubset
    so: setobject
    other: object
    /

Report whether another set contains this set.
[clinic start generated code]*/

static PyObject *
set_issubset_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=b2b59d5f314555ce input=f2a4fd0f2537758b]*/
{
    setentry *entry;
    Py_ssize_t pos = 0;
    int rv;

    if (!PyAnySet_Check(other)) {
        PyObject *tmp = set_intersection(so, other);
        if (tmp == NULL) {
            return NULL;
        }
        int result = (PySet_GET_SIZE(tmp) == PySet_GET_SIZE(so));
        Py_DECREF(tmp);
        return PyBool_FromLong(result);
    }
    if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
        Py_RETURN_FALSE;

    while (set_next(so, &pos, &entry)) {
        PyObject *key = entry->key;
        Py_INCREF(key);
        rv = set_contains_entry((PySetObject *)other, key, entry->hash);
        Py_DECREF(key);
        if (rv < 0) {
            return NULL;
        }
        if (!rv) {
            Py_RETURN_FALSE;
        }
    }
    Py_RETURN_TRUE;
}

/*[clinic input]
@critical_section so other
set.issuperset
    so: setobject
    other: object
    /

Report whether this set contains another set.
[clinic start generated code]*/

static PyObject *
set_issuperset_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=ecf00ce552c09461 input=5f2e1f262e6e4ccc]*/
{
    if (PyAnySet_Check(other)) {
        return set_issubset(other, (PyObject *)so);
    }

    PyObject *key, *it = PyObject_GetIter(other);
    if (it == NULL) {
        return NULL;
    }
    while ((key = PyIter_Next(it)) != NULL) {
        int rv = set_contains_key(so, key);
        Py_DECREF(key);
        if (rv < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (!rv) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        return NULL;
    }
    Py_RETURN_TRUE;
}

static PyObject *
set_richcompare(PyObject *self, PyObject *w, int op)
{
    PySetObject *v = _PySet_CAST(self);
    PyObject *r1;
    int r2;

    if(!PyAnySet_Check(w))
        Py_RETURN_NOTIMPLEMENTED;

    switch (op) {
    case Py_EQ:
        if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
            Py_RETURN_FALSE;
        Py_hash_t v_hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(v->hash);
        Py_hash_t w_hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(((PySetObject *)w)->hash);
        if (v_hash != -1 && w_hash != -1 && v_hash != w_hash)
            Py_RETURN_FALSE;
        return set_issubset((PyObject*)v, w);
    case Py_NE:
        r1 = set_richcompare((PyObject*)v, w, Py_EQ);
        if (r1 == NULL)
            return NULL;
        r2 = PyObject_IsTrue(r1);
        Py_DECREF(r1);
        if (r2 < 0)
            return NULL;
        return PyBool_FromLong(!r2);
    case Py_LE:
        return set_issubset((PyObject*)v, w);
    case Py_GE:
        return set_issuperset((PyObject*)v, w);
    case Py_LT:
        if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
            Py_RETURN_FALSE;
        return set_issubset((PyObject*)v, w);
    case Py_GT:
        if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
            Py_RETURN_FALSE;
        return set_issuperset((PyObject*)v, w);
    }
    Py_RETURN_NOTIMPLEMENTED;
}

/*[clinic input]
@critical_section
set.add
    so: setobject
    object as key: object
    /

Add an element to a set.

This has no effect if the element is already present.
[clinic start generated code]*/

static PyObject *
set_add_impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=4cc4a937f1425c96 input=03baf62cb0e66514]*/
{
    if (set_add_key(so, key))
        return NULL;
    Py_RETURN_NONE;
}

int
_PySet_Contains(PySetObject *so, PyObject *key)
{
    assert(so);

    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1) {
        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) {
            set_unhashable_type(key);
            return -1;
        }
        PyErr_Clear();
        // Note that 'key' could be a set() or frozenset() object.  Unlike most
        // container types, set allows membership testing with a set key, even
        // though it is not hashable.
        Py_BEGIN_CRITICAL_SECTION(key);
        hash = frozenset_hash_impl(key);
        Py_END_CRITICAL_SECTION();
    }
    return set_contains_entry(so, key, hash);
}

static int
set_contains(PyObject *self, PyObject *key)
{
    PySetObject *so = _PySet_CAST(self);
    return _PySet_Contains(so, key);
}

/*[clinic input]
@coexist
set.__contains__
    so: setobject
    object as key: object
    /

x.__contains__(y) <==> y in x.
[clinic start generated code]*/

static PyObject *
set___contains___impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=b44863d034b3c70e input=cf4c72db704e4cf0]*/
{
    long result;

    result = _PySet_Contains(so, key);
    if (result < 0)
        return NULL;
    return PyBool_FromLong(result);
}

/*[clinic input]
@coexist
frozenset.__contains__
    so: setobject
    object as key: object
    /

x.__contains__(y) <==> y in x.
[clinic start generated code]*/

static PyObject *
frozenset___contains___impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=2301ed91bc3a6dd5 input=2f04922a98d8bab7]*/
{
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1) {
        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) {
            set_unhashable_type(key);
            return NULL;
        }
        PyErr_Clear();
        Py_BEGIN_CRITICAL_SECTION(key);
        hash = frozenset_hash_impl(key);
        Py_END_CRITICAL_SECTION();
    }
    setentry *entry; // unused
    int status = set_do_lookup(so, so->table, so->mask, key, hash, &entry,
                           set_compare_frozenset);
    if (status < 0)
        return NULL;
    return PyBool_FromLong(status);
}

/*[clinic input]
@critical_section
set.remove
    so: setobject
    object as key: object
    /

Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError.
[clinic start generated code]*/

static PyObject *
set_remove_impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=0b9134a2a2200363 input=893e1cb1df98227a]*/
{
    int rv;

    rv = set_discard_key(so, key);
    if (rv < 0) {
        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
            return NULL;
        PyErr_Clear();
        Py_hash_t hash;
        Py_BEGIN_CRITICAL_SECTION(key);
        hash = frozenset_hash_impl(key);
        Py_END_CRITICAL_SECTION();
        rv = set_discard_entry(so, key, hash);
        if (rv < 0)
            return NULL;
    }

    if (rv == DISCARD_NOTFOUND) {
        _PyErr_SetKeyError(key);
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
@critical_section
set.discard
    so: setobject
    object as key: object
    /

Remove an element from a set if it is a member.

Unlike set.remove(), the discard() method does not raise
an exception when an element is missing from the set.
[clinic start generated code]*/

static PyObject *
set_discard_impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=eec3b687bf32759e input=861cb7fb69b4def0]*/
{
    int rv;

    rv = set_discard_key(so, key);
    if (rv < 0) {
        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
            return NULL;
        PyErr_Clear();
        Py_hash_t hash;
        Py_BEGIN_CRITICAL_SECTION(key);
        hash = frozenset_hash_impl(key);
        Py_END_CRITICAL_SECTION();
        rv = set_discard_entry(so, key, hash);
        if (rv < 0)
            return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
@critical_section
set.__reduce__
    so: setobject

Return state information for pickling.
[clinic start generated code]*/

static PyObject *
set___reduce___impl(PySetObject *so)
/*[clinic end generated code: output=9af7d0e029df87ee input=59405a4249e82f71]*/
{
    PyObject *keys=NULL, *args=NULL, *result=NULL, *state=NULL;

    keys = PySequence_List((PyObject *)so);
    if (keys == NULL)
        goto done;
    args = PyTuple_Pack(1, keys);
    if (args == NULL)
        goto done;
    state = _PyObject_GetState((PyObject *)so);
    if (state == NULL)
        goto done;
    result = PyTuple_Pack(3, Py_TYPE(so), args, state);
done:
    Py_XDECREF(args);
    Py_XDECREF(keys);
    Py_XDECREF(state);
    return result;
}

/*[clinic input]
@critical_section
set.__sizeof__
    so: setobject

S.__sizeof__() -> size of S in memory, in bytes.
[clinic start generated code]*/

static PyObject *
set___sizeof___impl(PySetObject *so)
/*[clinic end generated code: output=4bfa3df7bd38ed88 input=09e1a09f168eaa23]*/
{
    size_t res = _PyObject_SIZE(Py_TYPE(so));
    if (so->table != so->smalltable) {
        res += ((size_t)so->mask + 1) * sizeof(setentry);
    }
    return PyLong_FromSize_t(res);
}

static int
set_init(PyObject *so, PyObject *args, PyObject *kwds)
{
    PySetObject *self = _PySet_CAST(so);
    PyObject *iterable = NULL;

    if (!_PyArg_NoKeywords("set", kwds))
        return -1;
    if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
        return -1;

    if (_PyObject_IsUniquelyReferenced((PyObject *)self) && self->fill == 0) {
        self->hash = -1;
        if (iterable == NULL) {
            return 0;
        }
        return set_update_local(self, iterable);
    }
    Py_BEGIN_CRITICAL_SECTION(self);
    if (self->fill)
        set_clear_internal((PyObject*)self);
    self->hash = -1;
    Py_END_CRITICAL_SECTION();

    if (iterable == NULL)
        return 0;
    return set_update_internal(self, iterable);
}

static PyObject*
set_vectorcall(PyObject *type, PyObject * const*args,
               size_t nargsf, PyObject *kwnames)
{
    assert(PyType_Check(type));

    if (!_PyArg_NoKwnames("set", kwnames)) {
        return NULL;
    }

    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
    if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
        return NULL;
    }

    if (nargs) {
        return make_new_set(_PyType_CAST(type), args[0]);
    }

    return make_new_set(_PyType_CAST(type), NULL);
}

static PySequenceMethods set_as_sequence = {
    set_len,                            /* sq_length */
    0,                                  /* sq_concat */
    0,                                  /* sq_repeat */
    0,                                  /* sq_item */
    0,                                  /* sq_slice */
    0,                                  /* sq_ass_item */
    0,                                  /* sq_ass_slice */
    set_contains,                       /* sq_contains */
};

/* set object ********************************************************/

static PyMethodDef set_methods[] = {
    SET_ADD_METHODDEF
    SET_CLEAR_METHODDEF
    SET___CONTAINS___METHODDEF
    SET_COPY_METHODDEF
    SET_DISCARD_METHODDEF
    SET_DIFFERENCE_MULTI_METHODDEF
    SET_DIFFERENCE_UPDATE_METHODDEF
    SET_INTERSECTION_MULTI_METHODDEF
    SET_INTERSECTION_UPDATE_MULTI_METHODDEF
    SET_ISDISJOINT_METHODDEF
    SET_ISSUBSET_METHODDEF
    SET_ISSUPERSET_METHODDEF
    SET_POP_METHODDEF
    SET___REDUCE___METHODDEF
    SET_REMOVE_METHODDEF
    SET___SIZEOF___METHODDEF
    SET_SYMMETRIC_DIFFERENCE_METHODDEF
    SET_SYMMETRIC_DIFFERENCE_UPDATE_METHODDEF
    SET_UNION_METHODDEF
    SET_UPDATE_METHODDEF
    {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS,
     PyDoc_STR("sets are generic over the type of their elements")},
    {NULL,              NULL}   /* sentinel */
};

static PyNumberMethods set_as_number = {
    0,                                  /*nb_add*/
    set_sub,                            /*nb_subtract*/
    0,                                  /*nb_multiply*/
    0,                                  /*nb_remainder*/
    0,                                  /*nb_divmod*/
    0,                                  /*nb_power*/
    0,                                  /*nb_negative*/
    0,                                  /*nb_positive*/
    0,                                  /*nb_absolute*/
    0,                                  /*nb_bool*/
    0,                                  /*nb_invert*/
    0,                                  /*nb_lshift*/
    0,                                  /*nb_rshift*/
    set_and,                            /*nb_and*/
    set_xor,                            /*nb_xor*/
    set_or,                             /*nb_or*/
    0,                                  /*nb_int*/
    0,                                  /*nb_reserved*/
    0,                                  /*nb_float*/
    0,                                  /*nb_inplace_add*/
    set_isub,                           /*nb_inplace_subtract*/
    0,                                  /*nb_inplace_multiply*/
    0,                                  /*nb_inplace_remainder*/
    0,                                  /*nb_inplace_power*/
    0,                                  /*nb_inplace_lshift*/
    0,                                  /*nb_inplace_rshift*/
    set_iand,                           /*nb_inplace_and*/
    set_ixor,                           /*nb_inplace_xor*/
    set_ior,                            /*nb_inplace_or*/
};

PyDoc_STRVAR(set_doc,
"set(iterable=(), /)\n\
--\n\
\n\
Build an unordered collection of unique elements.");

PyTypeObject PySet_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "set",                              /* tp_name */
    sizeof(PySetObject),                /* tp_basicsize */
    0,                                  /* tp_itemsize */
    /* methods */
    set_dealloc,                        /* tp_dealloc */
    0,                                  /* tp_vectorcall_offset */
    0,                                  /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_as_async */
    set_repr,                           /* tp_repr */
    &set_as_number,                     /* tp_as_number */
    &set_as_sequence,                   /* tp_as_sequence */
    0,                                  /* tp_as_mapping */
    PyObject_HashNotImplemented,        /* tp_hash */
    0,                                  /* tp_call */
    0,                                  /* tp_str */
    PyObject_GenericGetAttr,            /* tp_getattro */
    0,                                  /* tp_setattro */
    0,                                  /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASETYPE |
        _Py_TPFLAGS_MATCH_SELF,         /* tp_flags */
    set_doc,                            /* tp_doc */
    set_traverse,                       /* tp_traverse */
    set_clear_internal,                 /* tp_clear */
    set_richcompare,                    /* tp_richcompare */
    offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
    set_iter,                           /* tp_iter */
    0,                                  /* tp_iternext */
    set_methods,                        /* tp_methods */
    0,                                  /* tp_members */
    0,                                  /* tp_getset */
    0,                                  /* tp_base */
    0,                                  /* tp_dict */
    0,                                  /* tp_descr_get */
    0,                                  /* tp_descr_set */
    0,                                  /* tp_dictoffset */
    set_init,                           /* tp_init */
    _PyType_AllocNoTrack,               /* tp_alloc */
    set_new,                            /* tp_new */
    PyObject_GC_Del,                    /* tp_free */
    .tp_vectorcall = set_vectorcall,
    .tp_version_tag = _Py_TYPE_VERSION_SET,
};

/* frozenset object ********************************************************/


static PyMethodDef frozenset_methods[] = {
    FROZENSET___CONTAINS___METHODDEF
    FROZENSET_COPY_METHODDEF
    SET_DIFFERENCE_MULTI_METHODDEF
    SET_INTERSECTION_MULTI_METHODDEF
    SET_ISDISJOINT_METHODDEF
    SET_ISSUBSET_METHODDEF
    SET_ISSUPERSET_METHODDEF
    SET___REDUCE___METHODDEF
    SET___SIZEOF___METHODDEF
    SET_SYMMETRIC_DIFFERENCE_METHODDEF
    SET_UNION_METHODDEF
    {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS,
     PyDoc_STR("frozensets are generic over the type of their elements")},
    {NULL,              NULL}   /* sentinel */
};

static PyNumberMethods frozenset_as_number = {
    0,                                  /*nb_add*/
    set_sub,                            /*nb_subtract*/
    0,                                  /*nb_multiply*/
    0,                                  /*nb_remainder*/
    0,                                  /*nb_divmod*/
    0,                                  /*nb_power*/
    0,                                  /*nb_negative*/
    0,                                  /*nb_positive*/
    0,                                  /*nb_absolute*/
    0,                                  /*nb_bool*/
    0,                                  /*nb_invert*/
    0,                                  /*nb_lshift*/
    0,                                  /*nb_rshift*/
    set_and,                            /*nb_and*/
    set_xor,                            /*nb_xor*/
    set_or,                             /*nb_or*/
};

PyDoc_STRVAR(frozenset_doc,
"frozenset(iterable=(), /)\n\
--\n\
\n\
Build an immutable unordered collection of unique elements.");

PyTypeObject PyFrozenSet_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "frozenset",                        /* tp_name */
    sizeof(PySetObject),                /* tp_basicsize */
    0,                                  /* tp_itemsize */
    /* methods */
    set_dealloc,                        /* tp_dealloc */
    0,                                  /* tp_vectorcall_offset */
    0,                                  /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_as_async */
    set_repr,                           /* tp_repr */
    &frozenset_as_number,               /* tp_as_number */
    &set_as_sequence,                   /* tp_as_sequence */
    0,                                  /* tp_as_mapping */
    frozenset_hash,                     /* tp_hash */
    0,                                  /* tp_call */
    0,                                  /* tp_str */
    PyObject_GenericGetAttr,            /* tp_getattro */
    0,                                  /* tp_setattro */
    0,                                  /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASETYPE |
        _Py_TPFLAGS_MATCH_SELF,         /* tp_flags */
    frozenset_doc,                      /* tp_doc */
    set_traverse,                       /* tp_traverse */
    set_clear_internal,                 /* tp_clear */
    set_richcompare,                    /* tp_richcompare */
    offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
    set_iter,                           /* tp_iter */
    0,                                  /* tp_iternext */
    frozenset_methods,                  /* tp_methods */
    0,                                  /* tp_members */
    0,                                  /* tp_getset */
    0,                                  /* tp_base */
    0,                                  /* tp_dict */
    0,                                  /* tp_descr_get */
    0,                                  /* tp_descr_set */
    0,                                  /* tp_dictoffset */
    0,                                  /* tp_init */
    _PyType_AllocNoTrack,               /* tp_alloc */
    frozenset_new,                      /* tp_new */
    PyObject_GC_Del,                    /* tp_free */
    .tp_vectorcall = frozenset_vectorcall,
    .tp_version_tag = _Py_TYPE_VERSION_FROZEN_SET,
};


/***** C API functions *************************************************/

PyObject *
PySet_New(PyObject *iterable)
{
    return make_new_set(&PySet_Type, iterable);
}

PyObject *
PyFrozenSet_New(PyObject *iterable)
{
    PyObject *result = make_new_set(&PyFrozenSet_Type, iterable);
    if (result != NULL) {
        _PyFrozenSet_MaybeUntrack(result);
    }
    return result;
}

Py_ssize_t
PySet_Size(PyObject *anyset)
{
    if (!PyAnySet_Check(anyset)) {
        PyErr_BadInternalCall();
        return -1;
    }
    return set_len(anyset);
}

int
PySet_Clear(PyObject *set)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    (void)set_clear(set, NULL);
    return 0;
}

void
_PySet_ClearInternal(PySetObject *so)
{
    (void)set_clear_internal((PyObject*)so);
}

int
PySet_Contains(PyObject *anyset, PyObject *key)
{
    if (!PyAnySet_Check(anyset)) {
        PyErr_BadInternalCall();
        return -1;
    }

    PySetObject *so = (PySetObject *)anyset;
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1) {
        set_unhashable_type(key);
        return -1;
    }
    return set_contains_entry(so, key, hash);
}

int
PySet_Discard(PyObject *set, PyObject *key)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }

    int rv;
    Py_BEGIN_CRITICAL_SECTION(set);
    rv = set_discard_key((PySetObject *)set, key);
    Py_END_CRITICAL_SECTION();
    return rv;
}

int
PySet_Add(PyObject *anyset, PyObject *key)
{
    if (PySet_Check(anyset)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(anyset);
        rv = set_add_key((PySetObject *)anyset, key);
        Py_END_CRITICAL_SECTION();
        return rv;
    }

    if (PyFrozenSet_Check(anyset) && _PyObject_IsUniquelyReferenced(anyset)) {
        // We can only change frozensets if they are uniquely referenced. The
        // API limits the usage of `PySet_Add` to "fill in the values of brand
        // new frozensets before they are exposed to other code". In this case,
        // this can be done without a lock.
        // Since another key is added to the set, we must track the frozenset
        // if needed.
        if (PyFrozenSet_CheckExact(anyset) && !PyObject_GC_IsTracked(anyset) && PyObject_GC_IsTracked(key)) {
            _PyObject_GC_TRACK(anyset);
        }
        return set_add_key((PySetObject *)anyset, key);
    }

    PyErr_BadInternalCall();
    return -1;
}

int
_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
    setentry *entry;

    if (!PyAnySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    if (set_next((PySetObject *)set, pos, &entry) == 0)
        return 0;
    *key = entry->key;
    *hash = entry->hash;
    return 1;
}

int
_PySet_NextEntryRef(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
    setentry *entry;

    if (!PyAnySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(set);
    if (set_next((PySetObject *)set, pos, &entry) == 0)
        return 0;
    *key = Py_NewRef(entry->key);
    *hash = entry->hash;
    return 1;
}

PyObject *
PySet_Pop(PyObject *set)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    return set_pop(set, NULL);
}

int
_PySet_Update(PyObject *set, PyObject *iterable)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    return set_update_internal((PySetObject *)set, iterable);
}

/* Exported for the gdb plugin's benefit. */
PyObject *_PySet_Dummy = dummy;

/***** Dummy Struct  *************************************************/

static PyObject *
dummy_repr(PyObject *op)
{
    return PyUnicode_FromString("<dummy key>");
}

static void _Py_NO_RETURN
dummy_dealloc(PyObject* ignore)
{
    Py_FatalError("deallocating <dummy key>");
}

static PyTypeObject _PySetDummy_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "<dummy key> type",
    0,
    0,
    dummy_dealloc,      /*tp_dealloc*/ /*never called*/
    0,                  /*tp_vectorcall_offset*/
    0,                  /*tp_getattr*/
    0,                  /*tp_setattr*/
    0,                  /*tp_as_async*/
    dummy_repr,         /*tp_repr*/
    0,                  /*tp_as_number*/
    0,                  /*tp_as_sequence*/
    0,                  /*tp_as_mapping*/
    0,                  /*tp_hash */
    0,                  /*tp_call */
    0,                  /*tp_str */
    0,                  /*tp_getattro */
    0,                  /*tp_setattro */
    0,                  /*tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /*tp_flags */
};

static PyObject _dummy_struct = _PyObject_HEAD_INIT(&_PySetDummy_Type);
