Krikri::PySet
Emulation of CPython 3.13's set iteration order for INT elements (the
order Ansible's union / intersect / difference /
symmetric_difference filters return, since they are
list(set(a) OP set(b))). Small-int hashes are deterministic, so the order
is reproducible: it is the open-addressing table order of Objects/setobject.c
(linear probing of 9 slots, then the perturbed jump, growth x4 at 3/5
load). String sets are hash-randomized per real process and cannot be
matched - callers must only use this for lists of plain integers.
Constants
setobject.c stores a deleted entry as key=<dummy>, hash=-1; no integer hash can collide with it (int hashes are |n| mod 261-1, so they never reach 264-1), which makes this a safe marker for a tombstone slot.
Constructors
Class methods
setobject.c set_difference: when len(a)>>2 > len(b) it copies a and discards b's members (entries keep their slots); otherwise it iterates a in table order adding the elements not in b to a fresh set. list(set(a) - set(b))
setobject.c set_intersection for set & set: iterate the SMALLER set (b when the sizes are equal) in table order, adding hits to a fresh set. list(set(a) & set(b))
CPython hash(int): |n| mod (2**61 - 1) with the sign restored, -1 -> -2, reinterpreted as an unsigned 64-bit value.
setobject.c set_symmetric_difference for set(a) ^ set(b): the result
starts as a copy of set(b), then every entry of set(a) - in set(a)'s
own table order - is either tombstoned in the result (when it is also a
member of b) or added to it. That leaves the result's iteration order
shaped by where the tombstones and the fresh inserts landed, which is
why this cannot be derived from the other three operations.
list(set(a) ^ set(b))