blob: 8452546008bd1eafd67d89102e8e582f5079d8da [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
Raymond Hettinger64263df2017-09-04 18:54:16 -070015 us with a hybrid of linear probing and randomized probing. The linear probing
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070016 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
Raymond Hettinger64263df2017-09-04 18:54:16 -070018 we then use more of the upper bits from the hash value and apply a simple
19 linear congruential random number genearator. This helps break-up long
20 chains of collisions.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070021
22 All arithmetic on hash should ignore overflow.
23
Raymond Hettinger4d45c102015-01-25 16:27:40 -080024 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070025 NULL if the rich comparison returns an error.
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +030026
Raymond Hettinger64263df2017-09-04 18:54:16 -070027 Use cases for sets differ considerably from dictionaries where looked-up
28 keys are more likely to be present. In contrast, sets are primarily
29 about membership testing where the presence of an element is not known in
30 advance. Accordingly, the set implementation needs to optimize for both
31 the found and not-found case.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032*/
33
Raymond Hettingera690a992003-11-16 16:17:49 +000034#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020035#include "pycore_object.h" // _PyObject_GC_UNTRACK()
36#include <stddef.h> // offsetof()
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050039static PyObject _dummy_struct;
40
41#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000042
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070044/* ======================================================================== */
45/* ======= Begin logic for probing the hash table ========================= */
46
Raymond Hettinger710a67e2013-09-21 20:17:31 -070047/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070048#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070049#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070050#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070051
52/* This must be >= 1 */
53#define PERTURB_SHIFT 5
54
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000055static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020056set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057{
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020059 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070060 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070061 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080062 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070063 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070064 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000065
Raymond Hettinger70559b52015-07-23 07:42:23 -040066 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070067 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070069
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070070 perturb = hash;
71
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070072 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080073 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070074 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080075 /* startkey cannot be a dummy because the dummy hash field is -1 */
76 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080077 if (startkey == key)
78 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080079 if (PyUnicode_CheckExact(startkey)
80 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070081 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080082 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040083 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 Py_INCREF(startkey);
85 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
86 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010087 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010089 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010091 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070092 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060093 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070094 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070095
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080097 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080098 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070099 if (entry->hash == 0 && entry->key == NULL)
100 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800101 if (entry->hash == hash) {
102 PyObject *startkey = entry->key;
103 assert(startkey != dummy);
104 if (startkey == key)
105 return entry;
106 if (PyUnicode_CheckExact(startkey)
107 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700108 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800109 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400110 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800111 Py_INCREF(startkey);
112 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
113 Py_DECREF(startkey);
114 if (cmp < 0)
115 return NULL;
116 if (table != so->table || entry->key != startkey)
117 return set_lookkey(so, key, hash);
118 if (cmp > 0)
119 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600120 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800121 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122 }
123 }
124
125 perturb >>= PERTURB_SHIFT;
126 i = (i * 5 + 1 + perturb) & mask;
127
Raymond Hettinger70559b52015-07-23 07:42:23 -0400128 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700129 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700130 return entry;
131 }
132}
133
Raymond Hettinger15f08692015-07-03 17:21:17 -0700134static int set_table_resize(PySetObject *, Py_ssize_t);
135
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400137set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700138{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400139 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700140 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700141 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700142 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400143 size_t mask;
144 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700145 size_t j;
146 int cmp;
147
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400148 /* Pre-increment is necessary to prevent arbitrary code in the rich
149 comparison from deallocating the key just before the insertion. */
150 Py_INCREF(key);
151
152 restart:
153
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400154 mask = so->mask;
155 i = (size_t)hash & mask;
156
Raymond Hettinger70559b52015-07-23 07:42:23 -0400157 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700159 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700160
161 freeslot = NULL;
162 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700163
164 while (1) {
165 if (entry->hash == hash) {
166 PyObject *startkey = entry->key;
167 /* startkey cannot be a dummy because the dummy hash field is -1 */
168 assert(startkey != dummy);
169 if (startkey == key)
170 goto found_active;
171 if (PyUnicode_CheckExact(startkey)
172 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700173 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400175 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700176 Py_INCREF(startkey);
177 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
178 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700179 if (cmp > 0) /* likely */
180 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700181 if (cmp < 0)
182 goto comparison_error;
183 /* Continuing the search from the current entry only makes
184 sense if the table and entry are unchanged; otherwise,
185 we have to restart from the beginning */
186 if (table != so->table || entry->key != startkey)
187 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700188 mask = so->mask; /* help avoid a register spill */
189 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800190 else if (entry->hash == -1)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700191 freeslot = entry;
192
193 if (i + LINEAR_PROBES <= mask) {
194 for (j = 0 ; j < LINEAR_PROBES ; j++) {
195 entry++;
196 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700197 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700198 if (entry->hash == hash) {
199 PyObject *startkey = entry->key;
200 assert(startkey != dummy);
201 if (startkey == key)
202 goto found_active;
203 if (PyUnicode_CheckExact(startkey)
204 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700205 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700206 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400207 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700208 Py_INCREF(startkey);
209 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
210 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700211 if (cmp > 0)
212 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700213 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400214 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700215 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400216 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700217 mask = so->mask;
218 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800219 else if (entry->hash == -1)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800220 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700221 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700223
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700224 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800225 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700226
Raymond Hettinger70559b52015-07-23 07:42:23 -0400227 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700228 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700229 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700231
Raymond Hettinger15f08692015-07-03 17:21:17 -0700232 found_unused_or_dummy:
233 if (freeslot == NULL)
234 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700235 so->used++;
236 freeslot->key = key;
237 freeslot->hash = hash;
238 return 0;
239
240 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700241 so->fill++;
242 so->used++;
243 entry->key = key;
244 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800245 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700246 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900247 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700248
249 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400250 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700251 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000252
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400253 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700254 Py_DECREF(key);
255 return -1;
256}
257
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000258/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000259Internal routine used by set_table_resize() to insert an item which is
260known to be absent from the set. This routine also assumes that
261the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800262there is also safety benefit since using set_add_entry() risks making
263a callback in the middle of a set_table_resize(), see issue 1456209.
264The caller is responsible for updating the key's reference count and
265the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000266*/
267static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800268set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200270 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700271 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800272 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700273 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000274
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700275 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800276 entry = &table[i];
277 if (entry->key == NULL)
278 goto found_null;
279 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800280 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800281 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800282 if (entry->key == NULL)
283 goto found_null;
284 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700285 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700286 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800287 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700289 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800290 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800291 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000292}
293
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700294/* ======== End logic for probing the hash table ========================== */
295/* ======================================================================== */
296
Thomas Wouters89f507f2006-12-13 04:49:30 +0000297/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000299keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000300actually be smaller than the old one.
301*/
302static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800306 Py_ssize_t oldmask = so->mask;
307 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 int is_oldtable_malloced;
309 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100314 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500315 size_t newsize = PySet_MINSIZE;
316 while (newsize <= (size_t)minused) {
317 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 /* Get space for a new table. */
321 oldtable = so->table;
322 assert(oldtable != NULL);
323 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 if (newsize == PySet_MINSIZE) {
326 /* A large table is shrinking, or we can't get any smaller. */
327 newtable = so->smalltable;
328 if (newtable == oldtable) {
329 if (so->fill == so->used) {
330 /* No dummies, so no point doing anything. */
331 return 0;
332 }
333 /* We're not going to resize it, but rebuild the
334 table anyway to purge old dummy entries.
335 Subtle: This is *necessary* if fill==size,
336 as set_lookkey needs at least one virgin slot to
337 terminate failing searches. If fill < size, it's
338 merely desirable, as dummies slow searches. */
339 assert(so->fill > so->used);
340 memcpy(small_copy, oldtable, sizeof(small_copy));
341 oldtable = small_copy;
342 }
343 }
344 else {
345 newtable = PyMem_NEW(setentry, newsize);
346 if (newtable == NULL) {
347 PyErr_NoMemory();
348 return -1;
349 }
350 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 /* Make the set empty, using the new table. */
353 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800355 so->mask = newsize - 1;
356 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 /* Copy the data over; this is refcount-neutral for active entries;
359 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800360 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800361 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800362 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800363 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800364 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800365 }
366 }
367 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800368 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800371 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 }
374 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 if (is_oldtable_malloced)
377 PyMem_DEL(oldtable);
378 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379}
380
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700382set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700384 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700386 entry = set_lookkey(so, key, hash);
387 if (entry != NULL)
388 return entry->key != NULL;
389 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000390}
391
392#define DISCARD_NOTFOUND 0
393#define DISCARD_FOUND 1
394
395static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700396set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800397{
398 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000400
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700401 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 if (entry == NULL)
403 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700404 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return DISCARD_NOTFOUND;
406 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800408 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 so->used--;
410 Py_DECREF(old_key);
411 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000412}
413
414static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700415set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000416{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200417 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000418
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700419 if (!PyUnicode_CheckExact(key) ||
420 (hash = ((PyASCIIObject *) key)->hash) == -1) {
421 hash = PyObject_Hash(key);
422 if (hash == -1)
423 return -1;
424 }
425 return set_add_entry(so, key, hash);
426}
427
428static int
429set_contains_key(PySetObject *so, PyObject *key)
430{
431 Py_hash_t hash;
432
433 if (!PyUnicode_CheckExact(key) ||
434 (hash = ((PyASCIIObject *) key)->hash) == -1) {
435 hash = PyObject_Hash(key);
436 if (hash == -1)
437 return -1;
438 }
439 return set_contains_entry(so, key, hash);
440}
441
442static int
443set_discard_key(PySetObject *so, PyObject *key)
444{
445 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200448 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 hash = PyObject_Hash(key);
450 if (hash == -1)
451 return -1;
452 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700453 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000454}
455
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700456static void
457set_empty_to_minsize(PySetObject *so)
458{
459 memset(so->smalltable, 0, sizeof(so->smalltable));
460 so->fill = 0;
461 so->used = 0;
462 so->mask = PySet_MINSIZE - 1;
463 so->table = so->smalltable;
464 so->hash = -1;
465}
466
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000467static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000468set_clear_internal(PySetObject *so)
469{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800470 setentry *entry;
471 setentry *table = so->table;
472 Py_ssize_t fill = so->fill;
473 Py_ssize_t used = so->used;
474 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000476
Raymond Hettinger583cd032013-09-07 22:06:35 -0700477 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 /* This is delicate. During the process of clearing the set,
481 * decrefs can cause the set to mutate. To avoid fatal confusion
482 * (voice of experience), we have to make the set empty before
483 * clearing the slots, and never refer to anything via so->ref while
484 * clearing.
485 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700487 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 else if (fill > 0) {
490 /* It's a small table with something that needs to be cleared.
491 * Afraid the only safe way is to copy the set entries into
492 * another small table first.
493 */
494 memcpy(small_copy, table, sizeof(small_copy));
495 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700496 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 }
498 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 /* Now we can finally clear things. If C had refcounts, we could
501 * assert that the refcount on table is 1 now, i.e. that this function
502 * has unique access to it, so decref side-effects can't alter it.
503 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800504 for (entry = table; used > 0; entry++) {
505 if (entry->key && entry->key != dummy) {
506 used--;
507 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 if (table_is_malloced)
512 PyMem_DEL(table);
513 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000514}
515
516/*
517 * Iterate over a set table. Use like so:
518 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000520 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000521 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000522 * while (set_next(yourset, &pos, &entry)) {
523 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000524 * }
525 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000528 */
529static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000530set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 Py_ssize_t i;
533 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700534 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 assert (PyAnySet_Check(so));
537 i = *pos_ptr;
538 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 entry = &so->table[i];
541 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700543 entry++;
544 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 *pos_ptr = i+1;
546 if (i > mask)
547 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700548 assert(entry != NULL);
549 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000551}
552
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000553static void
554set_dealloc(PySetObject *so)
555{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200556 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800557 Py_ssize_t used = so->used;
558
INADA Naokia6296d32017-08-24 14:55:17 +0900559 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 PyObject_GC_UnTrack(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200561 Py_TRASHCAN_BEGIN(so, set_dealloc)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 if (so->weakreflist != NULL)
563 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000564
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800565 for (entry = so->table; used > 0; entry++) {
566 if (entry->key && entry->key != dummy) {
567 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700568 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 }
570 }
571 if (so->table != so->smalltable)
572 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700573 Py_TYPE(so)->tp_free(so);
Jeroen Demeyer351c6742019-05-10 19:21:11 +0200574 Py_TRASHCAN_END
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000575}
576
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000577static PyObject *
578set_repr(PySetObject *so)
579{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200580 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 if (status != 0) {
584 if (status < 0)
585 return NULL;
586 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
587 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 /* shortcut for the empty set */
590 if (!so->used) {
591 Py_ReprLeave((PyObject*)so);
592 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
593 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 keys = PySequence_List((PyObject *)so);
596 if (keys == NULL)
597 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000598
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200599 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 listrepr = PyObject_Repr(keys);
601 Py_DECREF(keys);
602 if (listrepr == NULL)
603 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200606 if (tmp == NULL)
607 goto done;
608 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200609
Andy Lester55728702020-03-06 16:53:17 -0600610 if (!Py_IS_TYPE(so, &PySet_Type))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200611 result = PyUnicode_FromFormat("%s({%U})",
612 Py_TYPE(so)->tp_name,
613 listrepr);
614 else
615 result = PyUnicode_FromFormat("{%U}", listrepr);
616 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000617done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 Py_ReprLeave((PyObject*)so);
619 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000620}
621
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000623set_len(PyObject *so)
624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000626}
627
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000628static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000629set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000632 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200633 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700634 setentry *so_entry;
635 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 assert (PyAnySet_Check(so));
638 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 other = (PySetObject*)otherset;
641 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700642 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 return 0;
644 /* Do one big resize at the start, rather than
645 * incrementally resizing as we insert new keys. Expect
646 * that there will be no (or few) overlapping keys.
647 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800648 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900649 if (set_table_resize(so, (so->used + other->used)*2) != 0)
650 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700652 so_entry = so->table;
653 other_entry = other->table;
654
655 /* If our table is empty, and both tables have the same size, and
656 there are no dummies to eliminate, then just copy the pointers. */
657 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
658 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
659 key = other_entry->key;
660 if (key != NULL) {
661 assert(so_entry->key == NULL);
662 Py_INCREF(key);
663 so_entry->key = key;
664 so_entry->hash = other_entry->hash;
665 }
666 }
667 so->fill = other->fill;
668 so->used = other->used;
669 return 0;
670 }
671
672 /* If our table is empty, we can use set_insert_clean() */
673 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800674 setentry *newtable = so->table;
675 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800676 so->fill = other->used;
677 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800678 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700679 key = other_entry->key;
680 if (key != NULL && key != dummy) {
681 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800682 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700683 }
684 }
685 return 0;
686 }
687
688 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700689 for (i = 0; i <= other->mask; i++) {
690 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700691 key = other_entry->key;
692 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700693 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 }
696 }
697 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000698}
699
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000700static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530701set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000702{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800703 /* Make sure the search finger is in bounds */
Raymond Hettingerf9ec1b92018-11-11 14:35:47 -0800704 setentry *entry = so->table + (so->finger & so->mask);
705 setentry *limit = so->table + so->mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 if (so->used == 0) {
709 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
710 return NULL;
711 }
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800712 while (entry->key == NULL || entry->key==dummy) {
713 entry++;
714 if (entry > limit)
715 entry = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 }
717 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800719 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 so->used--;
Raymond Hettingercf5863f2018-11-09 02:31:56 -0800721 so->finger = entry - so->table + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000723}
724
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000725PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
726Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000727
728static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000729set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 Py_ssize_t pos = 0;
732 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000733
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 while (set_next(so, &pos, &entry))
735 Py_VISIT(entry->key);
736 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000737}
738
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700739/* Work to increase the bit dispersion for closely spaced hash values.
740 This is important because some use cases have many combinations of a
741 small number of elements with nearby hashes so that many distinct
742 combinations collapse to only a handful of distinct hash values. */
743
744static Py_uhash_t
745_shuffle_bits(Py_uhash_t h)
746{
747 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
748}
749
750/* Most of the constants in this hash algorithm are randomly chosen
751 large primes with "interesting bit patterns" and that passed tests
752 for good collision statistics on a variety of problematic datasets
753 including powersets and graph structures (such as David Eppstein's
754 graph recipes in Lib/test/test_set.py) */
755
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000756static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000757frozenset_hash(PyObject *self)
758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700760 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000762
Raymond Hettingerb501a272015-08-06 22:15:22 -0700763 if (so->hash != -1)
764 return so->hash;
765
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700766 /* Xor-in shuffled bits from every entry's hash field because xor is
767 commutative and a frozenset hash should be independent of order.
768
769 For speed, include null entries and dummy entries and then
770 subtract out their effect afterwards so that the final hash
771 depends only on active entries. This allows the code to be
772 vectorized by the compiler and it saves the unpredictable
773 branches that would arise when trying to exclude null and dummy
774 entries on every iteration. */
775
776 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
777 hash ^= _shuffle_bits(entry->hash);
778
Raymond Hettingera286a512015-08-01 11:07:11 -0700779 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700780 if ((so->mask + 1 - so->fill) & 1)
781 hash ^= _shuffle_bits(0);
782
783 /* Remove the effect of an odd number of dummy entries */
784 if ((so->fill - so->used) & 1)
785 hash ^= _shuffle_bits(-1);
786
Raymond Hettinger41481952015-08-07 00:43:39 -0700787 /* Factor in the number of active entries */
788 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
789
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700790 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800791 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800792 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700793
Raymond Hettinger36c05002015-08-01 10:57:42 -0700794 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200795 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800796 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 so->hash = hash;
799 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000800}
801
Raymond Hettingera9d99362005-08-05 00:01:15 +0000802/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000803
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000804typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 PyObject_HEAD
806 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
807 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700808 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000810} setiterobject;
811
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000812static void
813setiter_dealloc(setiterobject *si)
814{
INADA Naokia6296d32017-08-24 14:55:17 +0900815 /* bpo-31095: UnTrack is needed before calling any callbacks */
816 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 Py_XDECREF(si->si_set);
818 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000819}
820
821static int
822setiter_traverse(setiterobject *si, visitproc visit, void *arg)
823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 Py_VISIT(si->si_set);
825 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000826}
827
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000828static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530829setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 Py_ssize_t len = 0;
832 if (si->si_set != NULL && si->si_used == si->si_set->used)
833 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000834 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000835}
836
Armin Rigof5b3e362006-02-11 21:32:43 +0000837PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000838
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000839static PyObject *setiter_iternext(setiterobject *si);
840
841static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530842setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000843{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200844 _Py_IDENTIFIER(iter);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300845 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500846 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000847 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300848
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000849 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500850 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000851 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500852 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000853 return NULL;
854 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200855 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000856}
857
858PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
859
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000860static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000862 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000864};
865
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000866static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000867{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700868 PyObject *key;
869 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200870 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 if (so == NULL)
874 return NULL;
875 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 if (si->si_used != so->used) {
878 PyErr_SetString(PyExc_RuntimeError,
879 "Set changed size during iteration");
880 si->si_used = -1; /* Make this state sticky */
881 return NULL;
882 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700883
884 i = si->si_pos;
885 assert(i>=0);
886 entry = so->table;
887 mask = so->mask;
888 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
889 i++;
890 si->si_pos = i+1;
891 if (i > mask)
892 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700894 key = entry[i].key;
895 Py_INCREF(key);
896 return key;
897
898fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700899 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300900 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700901 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000902}
903
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000904PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 PyVarObject_HEAD_INIT(&PyType_Type, 0)
906 "set_iterator", /* tp_name */
907 sizeof(setiterobject), /* tp_basicsize */
908 0, /* tp_itemsize */
909 /* methods */
910 (destructor)setiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200911 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 0, /* tp_getattr */
913 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200914 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 0, /* tp_repr */
916 0, /* tp_as_number */
917 0, /* tp_as_sequence */
918 0, /* tp_as_mapping */
919 0, /* tp_hash */
920 0, /* tp_call */
921 0, /* tp_str */
922 PyObject_GenericGetAttr, /* tp_getattro */
923 0, /* tp_setattro */
924 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700925 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 0, /* tp_doc */
927 (traverseproc)setiter_traverse, /* tp_traverse */
928 0, /* tp_clear */
929 0, /* tp_richcompare */
930 0, /* tp_weaklistoffset */
931 PyObject_SelfIter, /* tp_iter */
932 (iternextfunc)setiter_iternext, /* tp_iternext */
933 setiter_methods, /* tp_methods */
934 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000935};
936
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000937static PyObject *
938set_iter(PySetObject *so)
939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
941 if (si == NULL)
942 return NULL;
943 Py_INCREF(so);
944 si->si_set = so;
945 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700946 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 si->len = so->used;
948 _PyObject_GC_TRACK(si);
949 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000950}
951
Raymond Hettingerd7946662005-08-01 21:39:29 +0000952static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000953set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000954{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 if (PyAnySet_Check(other))
958 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 if (PyDict_CheckExact(other)) {
961 PyObject *value;
962 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000963 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200964 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 /* Do one big resize at the start, rather than
967 * incrementally resizing as we insert new keys. Expect
968 * that there will be no (or few) overlapping keys.
969 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700970 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800972 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900973 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 return -1;
975 }
976 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700977 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 return -1;
979 }
980 return 0;
981 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 it = PyObject_GetIter(other);
984 if (it == NULL)
985 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700988 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 Py_DECREF(it);
990 Py_DECREF(key);
991 return -1;
992 }
993 Py_DECREF(key);
994 }
995 Py_DECREF(it);
996 if (PyErr_Occurred())
997 return -1;
998 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000999}
1000
1001static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001002set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1007 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001008 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 return NULL;
1010 }
1011 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001012}
1013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001015"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001016
Raymond Hettinger426d9952014-05-18 21:40:20 +01001017/* XXX Todo:
1018 If aligned memory allocations become available, make the
1019 set object 64 byte aligned so that most of the fields
1020 can be retrieved or updated in a single cache line.
1021*/
1022
Raymond Hettingera38123e2003-11-24 22:18:49 +00001023static PyObject *
1024make_new_set(PyTypeObject *type, PyObject *iterable)
1025{
Dong-hee Na1c605672020-03-19 02:30:50 +09001026 assert(PyType_Check(type));
Raymond Hettinger8421d712016-04-29 01:37:05 -07001027 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001028
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001029 so = (PySetObject *)type->tp_alloc(type, 0);
1030 if (so == NULL)
1031 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001032
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001033 so->fill = 0;
1034 so->used = 0;
1035 so->mask = PySet_MINSIZE - 1;
1036 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001037 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001038 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001042 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 Py_DECREF(so);
1044 return NULL;
1045 }
1046 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001049}
1050
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001051static PyObject *
1052make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1055 if (PyType_IsSubtype(type, &PySet_Type))
1056 type = &PySet_Type;
1057 else
1058 type = &PyFrozenSet_Type;
1059 }
1060 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001061}
1062
Raymond Hettingerd7946662005-08-01 21:39:29 +00001063/* The empty frozenset is a singleton */
1064static PyObject *emptyfrozenset = NULL;
1065
Raymond Hettingera690a992003-11-16 16:17:49 +00001066static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001067make_new_frozenset(PyTypeObject *type, PyObject *iterable)
Raymond Hettingera690a992003-11-16 16:17:49 +00001068{
Dong-hee Na1c605672020-03-19 02:30:50 +09001069 if (type != &PyFrozenSet_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 return make_new_set(type, iterable);
Dong-hee Na1c605672020-03-19 02:30:50 +09001071 }
Raymond Hettingerd7946662005-08-01 21:39:29 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 if (iterable != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 if (PyFrozenSet_CheckExact(iterable)) {
Dong-hee Na1c605672020-03-19 02:30:50 +09001075 /* frozenset(f) is idempotent */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 Py_INCREF(iterable);
1077 return iterable;
1078 }
Dong-hee Na1c605672020-03-19 02:30:50 +09001079 PyObject *res = make_new_set((PyTypeObject *)type, iterable);
1080 if (res == NULL || PySet_GET_SIZE(res) != 0) {
1081 return res;
1082 }
1083 /* If the created frozenset is empty, return the empty frozenset singleton instead */
1084 Py_DECREF(res);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 }
Dong-hee Na1c605672020-03-19 02:30:50 +09001086
1087 // The empty frozenset is a singleton
1088 if (emptyfrozenset == NULL) {
1089 emptyfrozenset = make_new_set((PyTypeObject *)type, NULL);
1090 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 Py_XINCREF(emptyfrozenset);
1092 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001093}
1094
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001095static PyObject *
Dong-hee Na1c605672020-03-19 02:30:50 +09001096frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1097{
1098 PyObject *iterable = NULL;
1099
1100 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds)) {
1101 return NULL;
1102 }
1103
1104 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
1105 return NULL;
1106 }
1107
1108 return make_new_frozenset(type, iterable);
1109}
1110
1111static PyObject *
1112frozenset_vectorcall(PyObject *type, PyObject * const*args,
1113 size_t nargsf, PyObject *kwnames)
1114{
1115 if (!_PyArg_NoKwnames("frozenset", kwnames)) {
1116 return NULL;
1117 }
1118
1119 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1120 if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
1121 return NULL;
1122 }
1123
1124 PyObject *iterable = (nargs ? args[0] : NULL);
1125 return make_new_frozenset((PyTypeObject *)type, iterable);
1126}
1127
1128static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001129set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001132}
1133
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001134/* set_swap_bodies() switches the contents of any two sets by moving their
1135 internal data pointers and, if needed, copying the internal smalltables.
1136 Semantically equivalent to:
1137
1138 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1139
1140 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001141 Useful for operations that update in-place (by allowing an intermediate
1142 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001143*/
1144
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001145static void
1146set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 Py_ssize_t t;
1149 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001151 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 t = a->fill; a->fill = b->fill; b->fill = t;
1154 t = a->used; a->used = b->used; b->used = t;
1155 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 u = a->table;
1158 if (a->table == a->smalltable)
1159 u = b->smalltable;
1160 a->table = b->table;
1161 if (b->table == b->smalltable)
1162 a->table = a->smalltable;
1163 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 if (a->table == a->smalltable || b->table == b->smalltable) {
1166 memcpy(tab, a->smalltable, sizeof(tab));
1167 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1168 memcpy(b->smalltable, tab, sizeof(tab));
1169 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1172 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1173 h = a->hash; a->hash = b->hash; b->hash = h;
1174 } else {
1175 a->hash = -1;
1176 b->hash = -1;
1177 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001178}
1179
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001180static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301181set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001184}
1185
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001186static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301187frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 if (PyFrozenSet_CheckExact(so)) {
1190 Py_INCREF(so);
1191 return (PyObject *)so;
1192 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301193 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001194}
1195
Raymond Hettingera690a992003-11-16 16:17:49 +00001196PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1197
1198static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301199set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 set_clear_internal(so);
1202 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001203}
1204
1205PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1206
1207static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001208set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 PySetObject *result;
1211 PyObject *other;
1212 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001213
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301214 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 if (result == NULL)
1216 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1219 other = PyTuple_GET_ITEM(args, i);
1220 if ((PyObject *)so == other)
1221 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001222 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 Py_DECREF(result);
1224 return NULL;
1225 }
1226 }
1227 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001228}
1229
1230PyDoc_STRVAR(union_doc,
1231 "Return the union of sets as a new set.\n\
1232\n\
1233(i.e. all elements that are in either set.)");
1234
1235static PyObject *
1236set_or(PySetObject *so, PyObject *other)
1237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001239
Brian Curtindfc80e32011-08-10 20:28:54 -05001240 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1241 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001242
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301243 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 if (result == NULL)
1245 return NULL;
1246 if ((PyObject *)so == other)
1247 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001248 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 Py_DECREF(result);
1250 return NULL;
1251 }
1252 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001253}
1254
Raymond Hettingera690a992003-11-16 16:17:49 +00001255static PyObject *
1256set_ior(PySetObject *so, PyObject *other)
1257{
Brian Curtindfc80e32011-08-10 20:28:54 -05001258 if (!PyAnySet_Check(other))
1259 Py_RETURN_NOTIMPLEMENTED;
1260
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001261 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 return NULL;
1263 Py_INCREF(so);
1264 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001265}
1266
1267static PyObject *
1268set_intersection(PySetObject *so, PyObject *other)
1269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 PySetObject *result;
1271 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001272 Py_hash_t hash;
1273 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301276 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1279 if (result == NULL)
1280 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 if (PyAnySet_Check(other)) {
1283 Py_ssize_t pos = 0;
1284 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1287 tmp = (PyObject *)so;
1288 so = (PySetObject *)other;
1289 other = tmp;
1290 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001293 key = entry->key;
1294 hash = entry->hash;
1295 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001296 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 Py_DECREF(result);
1298 return NULL;
1299 }
1300 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001301 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 Py_DECREF(result);
1303 return NULL;
1304 }
1305 }
1306 }
1307 return (PyObject *)result;
1308 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 it = PyObject_GetIter(other);
1311 if (it == NULL) {
1312 Py_DECREF(result);
1313 return NULL;
1314 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001317 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001318 if (hash == -1)
1319 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001320 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001321 if (rv < 0)
1322 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001324 if (set_add_entry(result, key, hash))
1325 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 }
1327 Py_DECREF(key);
1328 }
1329 Py_DECREF(it);
1330 if (PyErr_Occurred()) {
1331 Py_DECREF(result);
1332 return NULL;
1333 }
1334 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001335 error:
1336 Py_DECREF(it);
1337 Py_DECREF(result);
1338 Py_DECREF(key);
1339 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001340}
1341
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001342static PyObject *
1343set_intersection_multi(PySetObject *so, PyObject *args)
1344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 Py_ssize_t i;
1346 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301349 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 Py_INCREF(so);
1352 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1353 PyObject *other = PyTuple_GET_ITEM(args, i);
1354 PyObject *newresult = set_intersection((PySetObject *)result, other);
1355 if (newresult == NULL) {
1356 Py_DECREF(result);
1357 return NULL;
1358 }
1359 Py_DECREF(result);
1360 result = newresult;
1361 }
1362 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001363}
1364
Raymond Hettingera690a992003-11-16 16:17:49 +00001365PyDoc_STRVAR(intersection_doc,
1366"Return the intersection of two sets as a new set.\n\
1367\n\
1368(i.e. all elements that are in both sets.)");
1369
1370static PyObject *
1371set_intersection_update(PySetObject *so, PyObject *other)
1372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 tmp = set_intersection(so, other);
1376 if (tmp == NULL)
1377 return NULL;
1378 set_swap_bodies(so, (PySetObject *)tmp);
1379 Py_DECREF(tmp);
1380 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001381}
1382
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001383static PyObject *
1384set_intersection_update_multi(PySetObject *so, PyObject *args)
1385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 tmp = set_intersection_multi(so, args);
1389 if (tmp == NULL)
1390 return NULL;
1391 set_swap_bodies(so, (PySetObject *)tmp);
1392 Py_DECREF(tmp);
1393 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001394}
1395
Raymond Hettingera690a992003-11-16 16:17:49 +00001396PyDoc_STRVAR(intersection_update_doc,
1397"Update a set with the intersection of itself and another.");
1398
1399static PyObject *
1400set_and(PySetObject *so, PyObject *other)
1401{
Brian Curtindfc80e32011-08-10 20:28:54 -05001402 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1403 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001405}
1406
1407static PyObject *
1408set_iand(PySetObject *so, PyObject *other)
1409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001411
Brian Curtindfc80e32011-08-10 20:28:54 -05001412 if (!PyAnySet_Check(other))
1413 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 result = set_intersection_update(so, other);
1415 if (result == NULL)
1416 return NULL;
1417 Py_DECREF(result);
1418 Py_INCREF(so);
1419 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001420}
1421
Guido van Rossum58da9312007-11-10 23:39:45 +00001422static PyObject *
1423set_isdisjoint(PySetObject *so, PyObject *other)
1424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001426 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 if ((PyObject *)so == other) {
1429 if (PySet_GET_SIZE(so) == 0)
1430 Py_RETURN_TRUE;
1431 else
1432 Py_RETURN_FALSE;
1433 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 if (PyAnySet_CheckExact(other)) {
1436 Py_ssize_t pos = 0;
1437 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1440 tmp = (PyObject *)so;
1441 so = (PySetObject *)other;
1442 other = tmp;
1443 }
1444 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001445 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001446 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 return NULL;
1448 if (rv)
1449 Py_RETURN_FALSE;
1450 }
1451 Py_RETURN_TRUE;
1452 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 it = PyObject_GetIter(other);
1455 if (it == NULL)
1456 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001459 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 if (hash == -1) {
1462 Py_DECREF(key);
1463 Py_DECREF(it);
1464 return NULL;
1465 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001466 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001468 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 Py_DECREF(it);
1470 return NULL;
1471 }
1472 if (rv) {
1473 Py_DECREF(it);
1474 Py_RETURN_FALSE;
1475 }
1476 }
1477 Py_DECREF(it);
1478 if (PyErr_Occurred())
1479 return NULL;
1480 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001481}
1482
1483PyDoc_STRVAR(isdisjoint_doc,
1484"Return True if two sets have a null intersection.");
1485
Neal Norwitz6576bd82005-11-13 18:41:28 +00001486static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001487set_difference_update_internal(PySetObject *so, PyObject *other)
1488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 if ((PyObject *)so == other)
1490 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 if (PyAnySet_Check(other)) {
1493 setentry *entry;
1494 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001495
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001496 /* Optimization: When the other set is more than 8 times
1497 larger than the base set, replace the other set with
1498 interesection of the two sets.
1499 */
1500 if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1501 other = set_intersection(so, other);
1502 if (other == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 return -1;
Raymond Hettinger88ea1662019-08-29 09:02:58 -07001504 } else {
1505 Py_INCREF(other);
1506 }
1507
1508 while (set_next((PySetObject *)other, &pos, &entry))
1509 if (set_discard_entry(so, entry->key, entry->hash) < 0) {
1510 Py_DECREF(other);
1511 return -1;
1512 }
1513
1514 Py_DECREF(other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 } else {
1516 PyObject *key, *it;
1517 it = PyObject_GetIter(other);
1518 if (it == NULL)
1519 return -1;
1520
1521 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001522 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 Py_DECREF(it);
1524 Py_DECREF(key);
1525 return -1;
1526 }
1527 Py_DECREF(key);
1528 }
1529 Py_DECREF(it);
1530 if (PyErr_Occurred())
1531 return -1;
1532 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001533 /* If more than 1/4th are dummies, then resize them away. */
1534 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001536 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001537}
1538
Raymond Hettingera690a992003-11-16 16:17:49 +00001539static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001540set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001541{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1545 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001546 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 return NULL;
1548 }
1549 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001550}
1551
1552PyDoc_STRVAR(difference_update_doc,
1553"Remove all elements of another set from this set.");
1554
1555static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001556set_copy_and_difference(PySetObject *so, PyObject *other)
1557{
1558 PyObject *result;
1559
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301560 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001561 if (result == NULL)
1562 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001563 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001564 return result;
1565 Py_DECREF(result);
1566 return NULL;
1567}
1568
1569static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001570set_difference(PySetObject *so, PyObject *other)
1571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001573 PyObject *key;
1574 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001576 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001577 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001578
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001579 if (PyAnySet_Check(other)) {
1580 other_size = PySet_GET_SIZE(other);
1581 }
1582 else if (PyDict_CheckExact(other)) {
1583 other_size = PyDict_GET_SIZE(other);
1584 }
1585 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001586 return set_copy_and_difference(so, other);
1587 }
1588
1589 /* If len(so) much more than len(other), it's more efficient to simply copy
1590 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001591 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001592 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 result = make_new_set_basetype(Py_TYPE(so), NULL);
1596 if (result == NULL)
1597 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001599 if (PyDict_CheckExact(other)) {
1600 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001601 key = entry->key;
1602 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001603 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001604 if (rv < 0) {
1605 Py_DECREF(result);
1606 return NULL;
1607 }
1608 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001609 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 Py_DECREF(result);
1611 return NULL;
1612 }
1613 }
1614 }
1615 return result;
1616 }
1617
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001618 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001620 key = entry->key;
1621 hash = entry->hash;
1622 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001623 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 Py_DECREF(result);
1625 return NULL;
1626 }
1627 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001628 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 Py_DECREF(result);
1630 return NULL;
1631 }
1632 }
1633 }
1634 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001635}
1636
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001637static PyObject *
1638set_difference_multi(PySetObject *so, PyObject *args)
1639{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 Py_ssize_t i;
1641 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301644 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 other = PyTuple_GET_ITEM(args, 0);
1647 result = set_difference(so, other);
1648 if (result == NULL)
1649 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1652 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001653 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 Py_DECREF(result);
1655 return NULL;
1656 }
1657 }
1658 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001659}
1660
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001661PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001662"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001663\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001664(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001665static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001666set_sub(PySetObject *so, PyObject *other)
1667{
Brian Curtindfc80e32011-08-10 20:28:54 -05001668 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1669 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001671}
1672
1673static PyObject *
1674set_isub(PySetObject *so, PyObject *other)
1675{
Brian Curtindfc80e32011-08-10 20:28:54 -05001676 if (!PyAnySet_Check(other))
1677 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001678 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 return NULL;
1680 Py_INCREF(so);
1681 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001682}
1683
1684static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001685set_symmetric_difference_update(PySetObject *so, PyObject *other)
1686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 PySetObject *otherset;
1688 PyObject *key;
1689 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001690 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001692 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301695 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 if (PyDict_CheckExact(other)) {
1698 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001700 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001701 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001702 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001703 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001705 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001706 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001707 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001708 Py_DECREF(key);
1709 return NULL;
1710 }
1711 }
Georg Brandl2d444492010-09-03 10:52:55 +00001712 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001713 }
1714 Py_RETURN_NONE;
1715 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 if (PyAnySet_Check(other)) {
1718 Py_INCREF(other);
1719 otherset = (PySetObject *)other;
1720 } else {
1721 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1722 if (otherset == NULL)
1723 return NULL;
1724 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001727 key = entry->key;
1728 hash = entry->hash;
1729 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001730 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 Py_DECREF(otherset);
1732 return NULL;
1733 }
1734 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001735 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 Py_DECREF(otherset);
1737 return NULL;
1738 }
1739 }
1740 }
1741 Py_DECREF(otherset);
1742 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001743}
1744
1745PyDoc_STRVAR(symmetric_difference_update_doc,
1746"Update a set with the symmetric difference of itself and another.");
1747
1748static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001749set_symmetric_difference(PySetObject *so, PyObject *other)
1750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 PyObject *rv;
1752 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1755 if (otherset == NULL)
1756 return NULL;
1757 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001758 if (rv == NULL) {
1759 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001761 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 Py_DECREF(rv);
1763 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001764}
1765
1766PyDoc_STRVAR(symmetric_difference_doc,
1767"Return the symmetric difference of two sets as a new set.\n\
1768\n\
1769(i.e. all elements that are in exactly one of the sets.)");
1770
1771static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001772set_xor(PySetObject *so, PyObject *other)
1773{
Brian Curtindfc80e32011-08-10 20:28:54 -05001774 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1775 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001776 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001777}
1778
1779static PyObject *
1780set_ixor(PySetObject *so, PyObject *other)
1781{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001783
Brian Curtindfc80e32011-08-10 20:28:54 -05001784 if (!PyAnySet_Check(other))
1785 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 result = set_symmetric_difference_update(so, other);
1787 if (result == NULL)
1788 return NULL;
1789 Py_DECREF(result);
1790 Py_INCREF(so);
1791 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001792}
1793
1794static PyObject *
1795set_issubset(PySetObject *so, PyObject *other)
1796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 setentry *entry;
1798 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001799 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 if (!PyAnySet_Check(other)) {
1802 PyObject *tmp, *result;
1803 tmp = make_new_set(&PySet_Type, other);
1804 if (tmp == NULL)
1805 return NULL;
1806 result = set_issubset(so, tmp);
1807 Py_DECREF(tmp);
1808 return result;
1809 }
1810 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1811 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001814 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001815 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 return NULL;
1817 if (!rv)
1818 Py_RETURN_FALSE;
1819 }
1820 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001821}
1822
1823PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1824
1825static PyObject *
1826set_issuperset(PySetObject *so, PyObject *other)
1827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 if (!PyAnySet_Check(other)) {
1831 tmp = make_new_set(&PySet_Type, other);
1832 if (tmp == NULL)
1833 return NULL;
1834 result = set_issuperset(so, tmp);
1835 Py_DECREF(tmp);
1836 return result;
1837 }
1838 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001839}
1840
1841PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1842
Raymond Hettingera690a992003-11-16 16:17:49 +00001843static PyObject *
1844set_richcompare(PySetObject *v, PyObject *w, int op)
1845{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001846 PyObject *r1;
1847 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001848
Brian Curtindfc80e32011-08-10 20:28:54 -05001849 if(!PyAnySet_Check(w))
1850 Py_RETURN_NOTIMPLEMENTED;
1851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 switch (op) {
1853 case Py_EQ:
1854 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1855 Py_RETURN_FALSE;
1856 if (v->hash != -1 &&
1857 ((PySetObject *)w)->hash != -1 &&
1858 v->hash != ((PySetObject *)w)->hash)
1859 Py_RETURN_FALSE;
1860 return set_issubset(v, w);
1861 case Py_NE:
1862 r1 = set_richcompare(v, w, Py_EQ);
1863 if (r1 == NULL)
1864 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001865 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001867 if (r2 < 0)
1868 return NULL;
1869 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001870 case Py_LE:
1871 return set_issubset(v, w);
1872 case Py_GE:
1873 return set_issuperset(v, w);
1874 case Py_LT:
1875 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1876 Py_RETURN_FALSE;
1877 return set_issubset(v, w);
1878 case Py_GT:
1879 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1880 Py_RETURN_FALSE;
1881 return set_issuperset(v, w);
1882 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001883 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001884}
1885
Raymond Hettingera690a992003-11-16 16:17:49 +00001886static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001887set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001888{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001889 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 return NULL;
1891 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001892}
1893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001895"Add an element to a set.\n\
1896\n\
1897This has no effect if the element is already present.");
1898
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001899static int
1900set_contains(PySetObject *so, PyObject *key)
1901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 PyObject *tmpkey;
1903 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001906 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1908 return -1;
1909 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001910 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (tmpkey == NULL)
1912 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001913 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 Py_DECREF(tmpkey);
1915 }
1916 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001917}
1918
1919static PyObject *
1920set_direct_contains(PySetObject *so, PyObject *key)
1921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001925 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 return NULL;
1927 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001928}
1929
1930PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1931
Raymond Hettingera690a992003-11-16 16:17:49 +00001932static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001933set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 PyObject *tmpkey;
1936 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001939 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1941 return NULL;
1942 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001943 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 if (tmpkey == NULL)
1945 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001948 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 return NULL;
1950 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001953 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 return NULL;
1955 }
1956 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001957}
1958
1959PyDoc_STRVAR(remove_doc,
1960"Remove an element from a set; it must be a member.\n\
1961\n\
1962If the element is not a member, raise a KeyError.");
1963
1964static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001965set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001966{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001967 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001971 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1973 return NULL;
1974 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001975 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 if (tmpkey == NULL)
1977 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001978 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001980 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001981 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 }
1983 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001984}
1985
1986PyDoc_STRVAR(discard_doc,
1987"Remove an element from a set if it is a member.\n\
1988\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001990
1991static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301992set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001993{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001995 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001996
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 keys = PySequence_List((PyObject *)so);
1998 if (keys == NULL)
1999 goto done;
2000 args = PyTuple_Pack(1, keys);
2001 if (args == NULL)
2002 goto done;
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03002003 if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) {
2004 goto done;
2005 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 dict = Py_None;
2008 Py_INCREF(dict);
2009 }
2010 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00002011done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 Py_XDECREF(args);
2013 Py_XDECREF(keys);
2014 Py_XDECREF(dict);
2015 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00002016}
2017
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002018static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302019set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002022
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002023 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 if (so->table != so->smalltable)
2025 res = res + (so->mask + 1) * sizeof(setentry);
2026 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002027}
2028
2029PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002030static int
2031set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2032{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002034
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03002035 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 return -1;
2037 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2038 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002039 if (self->fill)
2040 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 self->hash = -1;
2042 if (iterable == NULL)
2043 return 0;
2044 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002045}
2046
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002047static PyObject*
2048set_vectorcall(PyObject *type, PyObject * const*args,
2049 size_t nargsf, PyObject *kwnames)
2050{
2051 assert(PyType_Check(type));
2052
2053 if (!_PyArg_NoKwnames("set", kwnames)) {
2054 return NULL;
2055 }
2056
2057 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
2058 if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
2059 return NULL;
2060 }
2061
2062 if (nargs) {
2063 return make_new_set((PyTypeObject *)type, args[0]);
2064 }
2065
2066 return make_new_set((PyTypeObject *)type, NULL);
2067}
2068
Raymond Hettingera690a992003-11-16 16:17:49 +00002069static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 set_len, /* sq_length */
2071 0, /* sq_concat */
2072 0, /* sq_repeat */
2073 0, /* sq_item */
2074 0, /* sq_slice */
2075 0, /* sq_ass_item */
2076 0, /* sq_ass_slice */
2077 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002078};
2079
2080/* set object ********************************************************/
2081
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002082#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302083static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002084
2085PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2086All is well if assertions don't fail.");
2087#endif
2088
Raymond Hettingera690a992003-11-16 16:17:49 +00002089static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 {"add", (PyCFunction)set_add, METH_O,
2091 add_doc},
2092 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2093 clear_doc},
2094 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2095 contains_doc},
2096 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2097 copy_doc},
2098 {"discard", (PyCFunction)set_discard, METH_O,
2099 discard_doc},
2100 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2101 difference_doc},
2102 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2103 difference_update_doc},
2104 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2105 intersection_doc},
2106 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2107 intersection_update_doc},
2108 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2109 isdisjoint_doc},
2110 {"issubset", (PyCFunction)set_issubset, METH_O,
2111 issubset_doc},
2112 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2113 issuperset_doc},
2114 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2115 pop_doc},
2116 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2117 reduce_doc},
2118 {"remove", (PyCFunction)set_remove, METH_O,
2119 remove_doc},
2120 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2121 sizeof_doc},
2122 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2123 symmetric_difference_doc},
2124 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2125 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002126#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2128 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002129#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 {"union", (PyCFunction)set_union, METH_VARARGS,
2131 union_doc},
2132 {"update", (PyCFunction)set_update, METH_VARARGS,
2133 update_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002134 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002136};
2137
2138static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 0, /*nb_add*/
2140 (binaryfunc)set_sub, /*nb_subtract*/
2141 0, /*nb_multiply*/
2142 0, /*nb_remainder*/
2143 0, /*nb_divmod*/
2144 0, /*nb_power*/
2145 0, /*nb_negative*/
2146 0, /*nb_positive*/
2147 0, /*nb_absolute*/
2148 0, /*nb_bool*/
2149 0, /*nb_invert*/
2150 0, /*nb_lshift*/
2151 0, /*nb_rshift*/
2152 (binaryfunc)set_and, /*nb_and*/
2153 (binaryfunc)set_xor, /*nb_xor*/
2154 (binaryfunc)set_or, /*nb_or*/
2155 0, /*nb_int*/
2156 0, /*nb_reserved*/
2157 0, /*nb_float*/
2158 0, /*nb_inplace_add*/
2159 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2160 0, /*nb_inplace_multiply*/
2161 0, /*nb_inplace_remainder*/
2162 0, /*nb_inplace_power*/
2163 0, /*nb_inplace_lshift*/
2164 0, /*nb_inplace_rshift*/
2165 (binaryfunc)set_iand, /*nb_inplace_and*/
2166 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2167 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002168};
2169
2170PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002171"set() -> new empty set object\n\
2172set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002173\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002174Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002175
2176PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2178 "set", /* tp_name */
2179 sizeof(PySetObject), /* tp_basicsize */
2180 0, /* tp_itemsize */
2181 /* methods */
2182 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002183 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 0, /* tp_getattr */
2185 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002186 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002187 (reprfunc)set_repr, /* tp_repr */
2188 &set_as_number, /* tp_as_number */
2189 &set_as_sequence, /* tp_as_sequence */
2190 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002191 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 0, /* tp_call */
2193 0, /* tp_str */
2194 PyObject_GenericGetAttr, /* tp_getattro */
2195 0, /* tp_setattro */
2196 0, /* tp_as_buffer */
2197 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2198 Py_TPFLAGS_BASETYPE, /* tp_flags */
2199 set_doc, /* tp_doc */
2200 (traverseproc)set_traverse, /* tp_traverse */
2201 (inquiry)set_clear_internal, /* tp_clear */
2202 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002203 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2204 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002205 0, /* tp_iternext */
2206 set_methods, /* tp_methods */
2207 0, /* tp_members */
2208 0, /* tp_getset */
2209 0, /* tp_base */
2210 0, /* tp_dict */
2211 0, /* tp_descr_get */
2212 0, /* tp_descr_set */
2213 0, /* tp_dictoffset */
2214 (initproc)set_init, /* tp_init */
2215 PyType_GenericAlloc, /* tp_alloc */
2216 set_new, /* tp_new */
2217 PyObject_GC_Del, /* tp_free */
Dong-hee Na6ff79f652020-03-17 02:17:38 +09002218 .tp_vectorcall = set_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002219};
2220
2221/* frozenset object ********************************************************/
2222
2223
2224static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002225 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2226 contains_doc},
2227 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2228 copy_doc},
2229 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2230 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002231 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002232 intersection_doc},
2233 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2234 isdisjoint_doc},
2235 {"issubset", (PyCFunction)set_issubset, METH_O,
2236 issubset_doc},
2237 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2238 issuperset_doc},
2239 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2240 reduce_doc},
2241 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2242 sizeof_doc},
2243 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2244 symmetric_difference_doc},
2245 {"union", (PyCFunction)set_union, METH_VARARGS,
2246 union_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002247 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002249};
2250
2251static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002252 0, /*nb_add*/
2253 (binaryfunc)set_sub, /*nb_subtract*/
2254 0, /*nb_multiply*/
2255 0, /*nb_remainder*/
2256 0, /*nb_divmod*/
2257 0, /*nb_power*/
2258 0, /*nb_negative*/
2259 0, /*nb_positive*/
2260 0, /*nb_absolute*/
2261 0, /*nb_bool*/
2262 0, /*nb_invert*/
2263 0, /*nb_lshift*/
2264 0, /*nb_rshift*/
2265 (binaryfunc)set_and, /*nb_and*/
2266 (binaryfunc)set_xor, /*nb_xor*/
2267 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002268};
2269
2270PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002271"frozenset() -> empty frozenset object\n\
2272frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002273\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002274Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002275
2276PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2278 "frozenset", /* tp_name */
2279 sizeof(PySetObject), /* tp_basicsize */
2280 0, /* tp_itemsize */
2281 /* methods */
2282 (destructor)set_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002283 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 0, /* tp_getattr */
2285 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002286 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 (reprfunc)set_repr, /* tp_repr */
2288 &frozenset_as_number, /* tp_as_number */
2289 &set_as_sequence, /* tp_as_sequence */
2290 0, /* tp_as_mapping */
2291 frozenset_hash, /* tp_hash */
2292 0, /* tp_call */
2293 0, /* tp_str */
2294 PyObject_GenericGetAttr, /* tp_getattro */
2295 0, /* tp_setattro */
2296 0, /* tp_as_buffer */
2297 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2298 Py_TPFLAGS_BASETYPE, /* tp_flags */
2299 frozenset_doc, /* tp_doc */
2300 (traverseproc)set_traverse, /* tp_traverse */
2301 (inquiry)set_clear_internal, /* tp_clear */
2302 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002303 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 (getiterfunc)set_iter, /* tp_iter */
2305 0, /* tp_iternext */
2306 frozenset_methods, /* tp_methods */
2307 0, /* tp_members */
2308 0, /* tp_getset */
2309 0, /* tp_base */
2310 0, /* tp_dict */
2311 0, /* tp_descr_get */
2312 0, /* tp_descr_set */
2313 0, /* tp_dictoffset */
2314 0, /* tp_init */
2315 PyType_GenericAlloc, /* tp_alloc */
2316 frozenset_new, /* tp_new */
2317 PyObject_GC_Del, /* tp_free */
Dong-hee Na1c605672020-03-19 02:30:50 +09002318 .tp_vectorcall = frozenset_vectorcall,
Raymond Hettingera690a992003-11-16 16:17:49 +00002319};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002320
2321
2322/***** C API functions *************************************************/
2323
2324PyObject *
2325PySet_New(PyObject *iterable)
2326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002328}
2329
2330PyObject *
2331PyFrozenSet_New(PyObject *iterable)
2332{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002333 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002334}
2335
Neal Norwitz8c49c822006-03-04 18:41:19 +00002336Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002337PySet_Size(PyObject *anyset)
2338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 if (!PyAnySet_Check(anyset)) {
2340 PyErr_BadInternalCall();
2341 return -1;
2342 }
2343 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002344}
2345
2346int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002347PySet_Clear(PyObject *set)
2348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 if (!PySet_Check(set)) {
2350 PyErr_BadInternalCall();
2351 return -1;
2352 }
2353 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002354}
2355
2356int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002357PySet_Contains(PyObject *anyset, PyObject *key)
2358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 if (!PyAnySet_Check(anyset)) {
2360 PyErr_BadInternalCall();
2361 return -1;
2362 }
2363 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002364}
2365
2366int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002367PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 if (!PySet_Check(set)) {
2370 PyErr_BadInternalCall();
2371 return -1;
2372 }
2373 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002374}
2375
2376int
Christian Heimesfd66e512008-01-29 12:18:50 +00002377PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 if (!PySet_Check(anyset) &&
2380 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2381 PyErr_BadInternalCall();
2382 return -1;
2383 }
2384 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002385}
2386
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002387int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002388PySet_ClearFreeList(void)
2389{
2390 return 0;
2391}
2392
2393void
Victor Stinnerbed48172019-08-27 00:12:32 +02002394_PySet_Fini(void)
Raymond Hettinger3625af52016-03-27 01:15:07 -07002395{
2396 Py_CLEAR(emptyfrozenset);
2397}
2398
2399int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002400_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002402 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 if (!PyAnySet_Check(set)) {
2405 PyErr_BadInternalCall();
2406 return -1;
2407 }
2408 if (set_next((PySetObject *)set, pos, &entry) == 0)
2409 return 0;
2410 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002411 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002413}
2414
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002415PyObject *
2416PySet_Pop(PyObject *set)
2417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 if (!PySet_Check(set)) {
2419 PyErr_BadInternalCall();
2420 return NULL;
2421 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302422 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002423}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002424
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002425int
2426_PySet_Update(PyObject *set, PyObject *iterable)
2427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 if (!PySet_Check(set)) {
2429 PyErr_BadInternalCall();
2430 return -1;
2431 }
2432 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002433}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002434
Raymond Hettingere259f132013-12-15 11:56:14 -08002435/* Exported for the gdb plugin's benefit. */
2436PyObject *_PySet_Dummy = dummy;
2437
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002438#ifdef Py_DEBUG
2439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002440/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002441 Returns True and original set is restored. */
2442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443#define assertRaises(call_return_value, exception) \
2444 do { \
2445 assert(call_return_value); \
2446 assert(PyErr_ExceptionMatches(exception)); \
2447 PyErr_Clear(); \
2448 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002449
2450static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302451test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002453 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002454 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002456 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002458 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002461 /* Verify preconditions */
2462 assert(PyAnySet_Check(ob));
2463 assert(PyAnySet_CheckExact(ob));
2464 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 /* so.clear(); so |= set("abc"); */
2467 str = PyUnicode_FromString("abc");
2468 if (str == NULL)
2469 return NULL;
2470 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002471 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002472 Py_DECREF(str);
2473 return NULL;
2474 }
2475 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 /* Exercise type/size checks */
2478 assert(PySet_Size(ob) == 3);
2479 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 /* Raise TypeError for non-iterable constructor arguments */
2482 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2483 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 /* Raise TypeError for unhashable key */
2486 dup = PySet_New(ob);
2487 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2488 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2489 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 /* Exercise successful pop, contains, add, and discard */
2492 elem = PySet_Pop(ob);
2493 assert(PySet_Contains(ob, elem) == 0);
2494 assert(PySet_GET_SIZE(ob) == 2);
2495 assert(PySet_Add(ob, elem) == 0);
2496 assert(PySet_Contains(ob, elem) == 1);
2497 assert(PySet_GET_SIZE(ob) == 3);
2498 assert(PySet_Discard(ob, elem) == 1);
2499 assert(PySet_GET_SIZE(ob) == 2);
2500 assert(PySet_Discard(ob, elem) == 0);
2501 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002502
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002503 /* Exercise clear */
2504 dup2 = PySet_New(dup);
2505 assert(PySet_Clear(dup2) == 0);
2506 assert(PySet_Size(dup2) == 0);
2507 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 /* Raise SystemError on clear or update of frozen set */
2510 f = PyFrozenSet_New(dup);
2511 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2512 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2513 assert(PySet_Add(f, elem) == 0);
2514 Py_INCREF(f);
2515 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2516 Py_DECREF(f);
2517 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 /* Exercise direct iteration */
2520 i = 0, count = 0;
2521 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002522 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2524 count++;
2525 }
2526 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 /* Exercise updates */
2529 dup2 = PySet_New(NULL);
2530 assert(_PySet_Update(dup2, dup) == 0);
2531 assert(PySet_Size(dup2) == 3);
2532 assert(_PySet_Update(dup2, dup) == 0);
2533 assert(PySet_Size(dup2) == 3);
2534 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 /* Raise SystemError when self argument is not a set or frozenset. */
2537 t = PyTuple_New(0);
2538 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2539 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2540 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002542 /* Raise SystemError when self argument is not a set. */
2543 f = PyFrozenSet_New(dup);
2544 assert(PySet_Size(f) == 3);
2545 assert(PyFrozenSet_CheckExact(f));
2546 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2547 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2548 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002550 /* Raise KeyError when popping from an empty set */
2551 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2552 Py_DECREF(ob);
2553 assert(PySet_GET_SIZE(ob) == 0);
2554 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 /* Restore the set from the copy using the PyNumber API */
2557 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2558 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002560 /* Verify constructors accept NULL arguments */
2561 f = PySet_New(NULL);
2562 assert(f != NULL);
2563 assert(PySet_GET_SIZE(f) == 0);
2564 Py_DECREF(f);
2565 f = PyFrozenSet_New(NULL);
2566 assert(f != NULL);
2567 assert(PyFrozenSet_CheckExact(f));
2568 assert(PySet_GET_SIZE(f) == 0);
2569 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 Py_DECREF(elem);
2572 Py_DECREF(dup);
2573 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002574}
2575
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002576#undef assertRaises
2577
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002578#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002579
2580/***** Dummy Struct *************************************************/
2581
2582static PyObject *
2583dummy_repr(PyObject *op)
2584{
2585 return PyUnicode_FromString("<dummy key>");
2586}
2587
Victor Stinner2a4903f2020-01-30 13:09:11 +01002588static void _Py_NO_RETURN
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002589dummy_dealloc(PyObject* ignore)
2590{
2591 Py_FatalError("deallocating <dummy key>");
2592}
2593
2594static PyTypeObject _PySetDummy_Type = {
2595 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2596 "<dummy key> type",
2597 0,
2598 0,
2599 dummy_dealloc, /*tp_dealloc*/ /*never called*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002600 0, /*tp_vectorcall_offset*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002601 0, /*tp_getattr*/
2602 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002603 0, /*tp_as_async*/
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002604 dummy_repr, /*tp_repr*/
2605 0, /*tp_as_number*/
2606 0, /*tp_as_sequence*/
2607 0, /*tp_as_mapping*/
2608 0, /*tp_hash */
2609 0, /*tp_call */
2610 0, /*tp_str */
2611 0, /*tp_getattro */
2612 0, /*tp_setattro */
2613 0, /*tp_as_buffer */
2614 Py_TPFLAGS_DEFAULT, /*tp_flags */
2615};
2616
2617static PyObject _dummy_struct = {
2618 _PyObject_EXTRA_INIT
2619 2, &_PySetDummy_Type
2620};
2621