]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/Objects/setobject.c
AppPkg/.../Python-2.7.10: AppPkg.dsc, pyconfig.h, PyMod-2.7.10
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Objects / setobject.c
CommitLineData
53b2ba57
DM
1\r
2/* set object implementation\r
3 Written and maintained by Raymond D. Hettinger <python@rcn.com>\r
4 Derived from Lib/sets.py and Objects/dictobject.c.\r
5\r
6 Copyright (c) 2003-2007 Python Software Foundation.\r
7 All rights reserved.\r
8*/\r
9\r
10#include "Python.h"\r
11#include "structmember.h"\r
12\r
13/* Set a key error with the specified argument, wrapping it in a\r
14 * tuple automatically so that tuple keys are not unpacked as the\r
15 * exception arguments. */\r
16static void\r
17set_key_error(PyObject *arg)\r
18{\r
19 PyObject *tup;\r
20 tup = PyTuple_Pack(1, arg);\r
21 if (!tup)\r
22 return; /* caller will expect error to be set anyway */\r
23 PyErr_SetObject(PyExc_KeyError, tup);\r
24 Py_DECREF(tup);\r
25}\r
26\r
27/* This must be >= 1. */\r
28#define PERTURB_SHIFT 5\r
29\r
30/* Object used as dummy key to fill deleted entries */\r
31static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */\r
32\r
33#ifdef Py_REF_DEBUG\r
34PyObject *\r
35_PySet_Dummy(void)\r
36{\r
37 return dummy;\r
38}\r
39#endif\r
40\r
41#define INIT_NONZERO_SET_SLOTS(so) do { \\r
42 (so)->table = (so)->smalltable; \\r
43 (so)->mask = PySet_MINSIZE - 1; \\r
44 (so)->hash = -1; \\r
45 } while(0)\r
46\r
47#define EMPTY_TO_MINSIZE(so) do { \\r
48 memset((so)->smalltable, 0, sizeof((so)->smalltable)); \\r
49 (so)->used = (so)->fill = 0; \\r
50 INIT_NONZERO_SET_SLOTS(so); \\r
51 } while(0)\r
52\r
53/* Reuse scheme to save calls to malloc, free, and memset */\r
54#ifndef PySet_MAXFREELIST\r
55#define PySet_MAXFREELIST 80\r
56#endif\r
57static PySetObject *free_list[PySet_MAXFREELIST];\r
58static int numfree = 0;\r
59\r
60/*\r
61The basic lookup function used by all operations.\r
62This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.\r
63Open addressing is preferred over chaining since the link overhead for\r
64chaining would be substantial (100% with typical malloc overhead).\r
65\r
66The initial probe index is computed as hash mod the table size. Subsequent\r
67probe indices are computed as explained in Objects/dictobject.c.\r
68\r
69All arithmetic on hash should ignore overflow.\r
70\r
71Unlike the dictionary implementation, the lookkey functions can return\r
72NULL if the rich comparison returns an error.\r
73*/\r
74\r
75static setentry *\r
76set_lookkey(PySetObject *so, PyObject *key, register long hash)\r
77{\r
78 register Py_ssize_t i;\r
79 register size_t perturb;\r
80 register setentry *freeslot;\r
81 register size_t mask = so->mask;\r
82 setentry *table = so->table;\r
83 register setentry *entry;\r
84 register int cmp;\r
85 PyObject *startkey;\r
86\r
87 i = hash & mask;\r
88 entry = &table[i];\r
89 if (entry->key == NULL || entry->key == key)\r
90 return entry;\r
91\r
92 if (entry->key == dummy)\r
93 freeslot = entry;\r
94 else {\r
95 if (entry->hash == hash) {\r
96 startkey = entry->key;\r
97 Py_INCREF(startkey);\r
98 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);\r
99 Py_DECREF(startkey);\r
100 if (cmp < 0)\r
101 return NULL;\r
102 if (table == so->table && entry->key == startkey) {\r
103 if (cmp > 0)\r
104 return entry;\r
105 }\r
106 else {\r
107 /* The compare did major nasty stuff to the\r
108 * set: start over.\r
109 */\r
110 return set_lookkey(so, key, hash);\r
111 }\r
112 }\r
113 freeslot = NULL;\r
114 }\r
115\r
116 /* In the loop, key == dummy is by far (factor of 100s) the\r
117 least likely outcome, so test for that last. */\r
118 for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {\r
119 i = (i << 2) + i + perturb + 1;\r
120 entry = &table[i & mask];\r
121 if (entry->key == NULL) {\r
122 if (freeslot != NULL)\r
123 entry = freeslot;\r
124 break;\r
125 }\r
126 if (entry->key == key)\r
127 break;\r
128 if (entry->hash == hash && entry->key != dummy) {\r
129 startkey = entry->key;\r
130 Py_INCREF(startkey);\r
131 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);\r
132 Py_DECREF(startkey);\r
133 if (cmp < 0)\r
134 return NULL;\r
135 if (table == so->table && entry->key == startkey) {\r
136 if (cmp > 0)\r
137 break;\r
138 }\r
139 else {\r
140 /* The compare did major nasty stuff to the\r
141 * set: start over.\r
142 */\r
143 return set_lookkey(so, key, hash);\r
144 }\r
145 }\r
146 else if (entry->key == dummy && freeslot == NULL)\r
147 freeslot = entry;\r
148 }\r
149 return entry;\r
150}\r
151\r
152/*\r
153 * Hacked up version of set_lookkey which can assume keys are always strings;\r
154 * This means we can always use _PyString_Eq directly and not have to check to\r
155 * see if the comparison altered the table.\r
156 */\r
157static setentry *\r
158set_lookkey_string(PySetObject *so, PyObject *key, register long hash)\r
159{\r
160 register Py_ssize_t i;\r
161 register size_t perturb;\r
162 register setentry *freeslot;\r
163 register size_t mask = so->mask;\r
164 setentry *table = so->table;\r
165 register setentry *entry;\r
166\r
167 /* Make sure this function doesn't have to handle non-string keys,\r
168 including subclasses of str; e.g., one reason to subclass\r
169 strings is to override __eq__, and for speed we don't cater to\r
170 that here. */\r
171 if (!PyString_CheckExact(key)) {\r
172 so->lookup = set_lookkey;\r
173 return set_lookkey(so, key, hash);\r
174 }\r
175 i = hash & mask;\r
176 entry = &table[i];\r
177 if (entry->key == NULL || entry->key == key)\r
178 return entry;\r
179 if (entry->key == dummy)\r
180 freeslot = entry;\r
181 else {\r
182 if (entry->hash == hash && _PyString_Eq(entry->key, key))\r
183 return entry;\r
184 freeslot = NULL;\r
185 }\r
186\r
187 /* In the loop, key == dummy is by far (factor of 100s) the\r
188 least likely outcome, so test for that last. */\r
189 for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {\r
190 i = (i << 2) + i + perturb + 1;\r
191 entry = &table[i & mask];\r
192 if (entry->key == NULL)\r
193 return freeslot == NULL ? entry : freeslot;\r
194 if (entry->key == key\r
195 || (entry->hash == hash\r
196 && entry->key != dummy\r
197 && _PyString_Eq(entry->key, key)))\r
198 return entry;\r
199 if (entry->key == dummy && freeslot == NULL)\r
200 freeslot = entry;\r
201 }\r
202 assert(0); /* NOT REACHED */\r
203 return 0;\r
204}\r
205\r
206/*\r
207Internal routine to insert a new key into the table.\r
208Used by the public insert routine.\r
209Eats a reference to key.\r
210*/\r
211static int\r
212set_insert_key(register PySetObject *so, PyObject *key, long hash)\r
213{\r
214 register setentry *entry;\r
215\r
216 assert(so->lookup != NULL);\r
217 entry = so->lookup(so, key, hash);\r
218 if (entry == NULL)\r
219 return -1;\r
220 if (entry->key == NULL) {\r
221 /* UNUSED */\r
222 so->fill++;\r
223 entry->key = key;\r
224 entry->hash = hash;\r
225 so->used++;\r
226 } else if (entry->key == dummy) {\r
227 /* DUMMY */\r
228 entry->key = key;\r
229 entry->hash = hash;\r
230 so->used++;\r
231 Py_DECREF(dummy);\r
232 } else {\r
233 /* ACTIVE */\r
234 Py_DECREF(key);\r
235 }\r
236 return 0;\r
237}\r
238\r
239/*\r
240Internal routine used by set_table_resize() to insert an item which is\r
241known to be absent from the set. This routine also assumes that\r
242the set contains no deleted entries. Besides the performance benefit,\r
243using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).\r
244Note that no refcounts are changed by this routine; if needed, the caller\r
245is responsible for incref'ing `key`.\r
246*/\r
247static void\r
248set_insert_clean(register PySetObject *so, PyObject *key, long hash)\r
249{\r
250 register size_t i;\r
251 register size_t perturb;\r
252 register size_t mask = (size_t)so->mask;\r
253 setentry *table = so->table;\r
254 register setentry *entry;\r
255\r
256 i = hash & mask;\r
257 entry = &table[i];\r
258 for (perturb = hash; entry->key != NULL; perturb >>= PERTURB_SHIFT) {\r
259 i = (i << 2) + i + perturb + 1;\r
260 entry = &table[i & mask];\r
261 }\r
262 so->fill++;\r
263 entry->key = key;\r
264 entry->hash = hash;\r
265 so->used++;\r
266}\r
267\r
268/*\r
269Restructure the table by allocating a new table and reinserting all\r
270keys again. When entries have been deleted, the new table may\r
271actually be smaller than the old one.\r
272*/\r
273static int\r
274set_table_resize(PySetObject *so, Py_ssize_t minused)\r
275{\r
276 Py_ssize_t newsize;\r
277 setentry *oldtable, *newtable, *entry;\r
278 Py_ssize_t i;\r
279 int is_oldtable_malloced;\r
280 setentry small_copy[PySet_MINSIZE];\r
281\r
282 assert(minused >= 0);\r
283\r
284 /* Find the smallest table size > minused. */\r
285 for (newsize = PySet_MINSIZE;\r
286 newsize <= minused && newsize > 0;\r
287 newsize <<= 1)\r
288 ;\r
289 if (newsize <= 0) {\r
290 PyErr_NoMemory();\r
291 return -1;\r
292 }\r
293\r
294 /* Get space for a new table. */\r
295 oldtable = so->table;\r
296 assert(oldtable != NULL);\r
297 is_oldtable_malloced = oldtable != so->smalltable;\r
298\r
299 if (newsize == PySet_MINSIZE) {\r
300 /* A large table is shrinking, or we can't get any smaller. */\r
301 newtable = so->smalltable;\r
302 if (newtable == oldtable) {\r
303 if (so->fill == so->used) {\r
304 /* No dummies, so no point doing anything. */\r
305 return 0;\r
306 }\r
307 /* We're not going to resize it, but rebuild the\r
308 table anyway to purge old dummy entries.\r
309 Subtle: This is *necessary* if fill==size,\r
310 as set_lookkey needs at least one virgin slot to\r
311 terminate failing searches. If fill < size, it's\r
312 merely desirable, as dummies slow searches. */\r
313 assert(so->fill > so->used);\r
314 memcpy(small_copy, oldtable, sizeof(small_copy));\r
315 oldtable = small_copy;\r
316 }\r
317 }\r
318 else {\r
319 newtable = PyMem_NEW(setentry, newsize);\r
320 if (newtable == NULL) {\r
321 PyErr_NoMemory();\r
322 return -1;\r
323 }\r
324 }\r
325\r
326 /* Make the set empty, using the new table. */\r
327 assert(newtable != oldtable);\r
328 so->table = newtable;\r
329 so->mask = newsize - 1;\r
330 memset(newtable, 0, sizeof(setentry) * newsize);\r
331 so->used = 0;\r
332 i = so->fill;\r
333 so->fill = 0;\r
334\r
335 /* Copy the data over; this is refcount-neutral for active entries;\r
336 dummy entries aren't copied over, of course */\r
337 for (entry = oldtable; i > 0; entry++) {\r
338 if (entry->key == NULL) {\r
339 /* UNUSED */\r
340 ;\r
341 } else if (entry->key == dummy) {\r
342 /* DUMMY */\r
343 --i;\r
344 assert(entry->key == dummy);\r
345 Py_DECREF(entry->key);\r
346 } else {\r
347 /* ACTIVE */\r
348 --i;\r
349 set_insert_clean(so, entry->key, entry->hash);\r
350 }\r
351 }\r
352\r
353 if (is_oldtable_malloced)\r
354 PyMem_DEL(oldtable);\r
355 return 0;\r
356}\r
357\r
358/* CAUTION: set_add_key/entry() must guarantee it won't resize the table */\r
359\r
360static int\r
361set_add_entry(register PySetObject *so, setentry *entry)\r
362{\r
363 register Py_ssize_t n_used;\r
364 PyObject *key = entry->key;\r
365 long hash = entry->hash;\r
366\r
367 assert(so->fill <= so->mask); /* at least one empty slot */\r
368 n_used = so->used;\r
369 Py_INCREF(key);\r
370 if (set_insert_key(so, key, hash) == -1) {\r
371 Py_DECREF(key);\r
372 return -1;\r
373 }\r
374 if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))\r
375 return 0;\r
376 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);\r
377}\r
378\r
379static int\r
380set_add_key(register PySetObject *so, PyObject *key)\r
381{\r
382 register long hash;\r
383 register Py_ssize_t n_used;\r
384\r
385 if (!PyString_CheckExact(key) ||\r
386 (hash = ((PyStringObject *) key)->ob_shash) == -1) {\r
387 hash = PyObject_Hash(key);\r
388 if (hash == -1)\r
389 return -1;\r
390 }\r
391 assert(so->fill <= so->mask); /* at least one empty slot */\r
392 n_used = so->used;\r
393 Py_INCREF(key);\r
394 if (set_insert_key(so, key, hash) == -1) {\r
395 Py_DECREF(key);\r
396 return -1;\r
397 }\r
398 if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))\r
399 return 0;\r
400 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);\r
401}\r
402\r
403#define DISCARD_NOTFOUND 0\r
404#define DISCARD_FOUND 1\r
405\r
406static int\r
407set_discard_entry(PySetObject *so, setentry *oldentry)\r
408{ register setentry *entry;\r
409 PyObject *old_key;\r
410\r
411 entry = (so->lookup)(so, oldentry->key, oldentry->hash);\r
412 if (entry == NULL)\r
413 return -1;\r
414 if (entry->key == NULL || entry->key == dummy)\r
415 return DISCARD_NOTFOUND;\r
416 old_key = entry->key;\r
417 Py_INCREF(dummy);\r
418 entry->key = dummy;\r
419 so->used--;\r
420 Py_DECREF(old_key);\r
421 return DISCARD_FOUND;\r
422}\r
423\r
424static int\r
425set_discard_key(PySetObject *so, PyObject *key)\r
426{\r
427 register long hash;\r
428 register setentry *entry;\r
429 PyObject *old_key;\r
430\r
431 assert (PyAnySet_Check(so));\r
432 if (!PyString_CheckExact(key) ||\r
433 (hash = ((PyStringObject *) key)->ob_shash) == -1) {\r
434 hash = PyObject_Hash(key);\r
435 if (hash == -1)\r
436 return -1;\r
437 }\r
438 entry = (so->lookup)(so, key, hash);\r
439 if (entry == NULL)\r
440 return -1;\r
441 if (entry->key == NULL || entry->key == dummy)\r
442 return DISCARD_NOTFOUND;\r
443 old_key = entry->key;\r
444 Py_INCREF(dummy);\r
445 entry->key = dummy;\r
446 so->used--;\r
447 Py_DECREF(old_key);\r
448 return DISCARD_FOUND;\r
449}\r
450\r
451static int\r
452set_clear_internal(PySetObject *so)\r
453{\r
454 setentry *entry, *table;\r
455 int table_is_malloced;\r
456 Py_ssize_t fill;\r
457 setentry small_copy[PySet_MINSIZE];\r
458#ifdef Py_DEBUG\r
459 Py_ssize_t i, n;\r
460 assert (PyAnySet_Check(so));\r
461\r
462 n = so->mask + 1;\r
463 i = 0;\r
464#endif\r
465\r
466 table = so->table;\r
467 assert(table != NULL);\r
468 table_is_malloced = table != so->smalltable;\r
469\r
470 /* This is delicate. During the process of clearing the set,\r
471 * decrefs can cause the set to mutate. To avoid fatal confusion\r
472 * (voice of experience), we have to make the set empty before\r
473 * clearing the slots, and never refer to anything via so->ref while\r
474 * clearing.\r
475 */\r
476 fill = so->fill;\r
477 if (table_is_malloced)\r
478 EMPTY_TO_MINSIZE(so);\r
479\r
480 else if (fill > 0) {\r
481 /* It's a small table with something that needs to be cleared.\r
482 * Afraid the only safe way is to copy the set entries into\r
483 * another small table first.\r
484 */\r
485 memcpy(small_copy, table, sizeof(small_copy));\r
486 table = small_copy;\r
487 EMPTY_TO_MINSIZE(so);\r
488 }\r
489 /* else it's a small table that's already empty */\r
490\r
491 /* Now we can finally clear things. If C had refcounts, we could\r
492 * assert that the refcount on table is 1 now, i.e. that this function\r
493 * has unique access to it, so decref side-effects can't alter it.\r
494 */\r
495 for (entry = table; fill > 0; ++entry) {\r
496#ifdef Py_DEBUG\r
497 assert(i < n);\r
498 ++i;\r
499#endif\r
500 if (entry->key) {\r
501 --fill;\r
502 Py_DECREF(entry->key);\r
503 }\r
504#ifdef Py_DEBUG\r
505 else\r
506 assert(entry->key == NULL);\r
507#endif\r
508 }\r
509\r
510 if (table_is_malloced)\r
511 PyMem_DEL(table);\r
512 return 0;\r
513}\r
514\r
515/*\r
516 * Iterate over a set table. Use like so:\r
517 *\r
518 * Py_ssize_t pos;\r
519 * setentry *entry;\r
520 * pos = 0; # important! pos should not otherwise be changed by you\r
521 * while (set_next(yourset, &pos, &entry)) {\r
522 * Refer to borrowed reference in entry->key.\r
523 * }\r
524 *\r
525 * CAUTION: In general, it isn't safe to use set_next in a loop that\r
526 * mutates the table.\r
527 */\r
528static int\r
529set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)\r
530{\r
531 Py_ssize_t i;\r
532 Py_ssize_t mask;\r
533 register setentry *table;\r
534\r
535 assert (PyAnySet_Check(so));\r
536 i = *pos_ptr;\r
537 assert(i >= 0);\r
538 table = so->table;\r
539 mask = so->mask;\r
540 while (i <= mask && (table[i].key == NULL || table[i].key == dummy))\r
541 i++;\r
542 *pos_ptr = i+1;\r
543 if (i > mask)\r
544 return 0;\r
545 assert(table[i].key != NULL);\r
546 *entry_ptr = &table[i];\r
547 return 1;\r
548}\r
549\r
550static void\r
551set_dealloc(PySetObject *so)\r
552{\r
553 register setentry *entry;\r
554 Py_ssize_t fill = so->fill;\r
555 PyObject_GC_UnTrack(so);\r
556 Py_TRASHCAN_SAFE_BEGIN(so)\r
557 if (so->weakreflist != NULL)\r
558 PyObject_ClearWeakRefs((PyObject *) so);\r
559\r
560 for (entry = so->table; fill > 0; entry++) {\r
561 if (entry->key) {\r
562 --fill;\r
563 Py_DECREF(entry->key);\r
564 }\r
565 }\r
566 if (so->table != so->smalltable)\r
567 PyMem_DEL(so->table);\r
568 if (numfree < PySet_MAXFREELIST && PyAnySet_CheckExact(so))\r
569 free_list[numfree++] = so;\r
570 else\r
571 Py_TYPE(so)->tp_free(so);\r
572 Py_TRASHCAN_SAFE_END(so)\r
573}\r
574\r
575static int\r
576set_tp_print(PySetObject *so, FILE *fp, int flags)\r
577{\r
578 setentry *entry;\r
579 Py_ssize_t pos=0;\r
580 char *emit = ""; /* No separator emitted on first pass */\r
581 char *separator = ", ";\r
582 int status = Py_ReprEnter((PyObject*)so);\r
583\r
584 if (status != 0) {\r
585 if (status < 0)\r
586 return status;\r
587 Py_BEGIN_ALLOW_THREADS\r
588 fprintf(fp, "%s(...)", so->ob_type->tp_name);\r
589 Py_END_ALLOW_THREADS\r
590 return 0;\r
591 }\r
592\r
593 Py_BEGIN_ALLOW_THREADS\r
594 fprintf(fp, "%s([", so->ob_type->tp_name);\r
595 Py_END_ALLOW_THREADS\r
596 while (set_next(so, &pos, &entry)) {\r
597 Py_BEGIN_ALLOW_THREADS\r
598 fputs(emit, fp);\r
599 Py_END_ALLOW_THREADS\r
600 emit = separator;\r
601 if (PyObject_Print(entry->key, fp, 0) != 0) {\r
602 Py_ReprLeave((PyObject*)so);\r
603 return -1;\r
604 }\r
605 }\r
606 Py_BEGIN_ALLOW_THREADS\r
607 fputs("])", fp);\r
608 Py_END_ALLOW_THREADS\r
609 Py_ReprLeave((PyObject*)so);\r
610 return 0;\r
611}\r
612\r
613static PyObject *\r
614set_repr(PySetObject *so)\r
615{\r
616 PyObject *keys, *result=NULL, *listrepr;\r
617 int status = Py_ReprEnter((PyObject*)so);\r
618\r
619 if (status != 0) {\r
620 if (status < 0)\r
621 return NULL;\r
622 return PyString_FromFormat("%s(...)", so->ob_type->tp_name);\r
623 }\r
624\r
625 keys = PySequence_List((PyObject *)so);\r
626 if (keys == NULL)\r
627 goto done;\r
628 listrepr = PyObject_Repr(keys);\r
629 Py_DECREF(keys);\r
630 if (listrepr == NULL)\r
631 goto done;\r
632\r
633 result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,\r
634 PyString_AS_STRING(listrepr));\r
635 Py_DECREF(listrepr);\r
636done:\r
637 Py_ReprLeave((PyObject*)so);\r
638 return result;\r
639}\r
640\r
641static Py_ssize_t\r
642set_len(PyObject *so)\r
643{\r
644 return ((PySetObject *)so)->used;\r
645}\r
646\r
647static int\r
648set_merge(PySetObject *so, PyObject *otherset)\r
649{\r
650 PySetObject *other;\r
651 PyObject *key;\r
652 long hash;\r
653 register Py_ssize_t i;\r
654 register setentry *entry;\r
655\r
656 assert (PyAnySet_Check(so));\r
657 assert (PyAnySet_Check(otherset));\r
658\r
659 other = (PySetObject*)otherset;\r
660 if (other == so || other->used == 0)\r
661 /* a.update(a) or a.update({}); nothing to do */\r
662 return 0;\r
663 /* Do one big resize at the start, rather than\r
664 * incrementally resizing as we insert new keys. Expect\r
665 * that there will be no (or few) overlapping keys.\r
666 */\r
667 if ((so->fill + other->used)*3 >= (so->mask+1)*2) {\r
668 if (set_table_resize(so, (so->used + other->used)*2) != 0)\r
669 return -1;\r
670 }\r
671 for (i = 0; i <= other->mask; i++) {\r
672 entry = &other->table[i];\r
673 key = entry->key;\r
674 hash = entry->hash;\r
675 if (key != NULL &&\r
676 key != dummy) {\r
677 Py_INCREF(key);\r
678 if (set_insert_key(so, key, hash) == -1) {\r
679 Py_DECREF(key);\r
680 return -1;\r
681 }\r
682 }\r
683 }\r
684 return 0;\r
685}\r
686\r
687static int\r
688set_contains_key(PySetObject *so, PyObject *key)\r
689{\r
690 long hash;\r
691 setentry *entry;\r
692\r
693 if (!PyString_CheckExact(key) ||\r
694 (hash = ((PyStringObject *) key)->ob_shash) == -1) {\r
695 hash = PyObject_Hash(key);\r
696 if (hash == -1)\r
697 return -1;\r
698 }\r
699 entry = (so->lookup)(so, key, hash);\r
700 if (entry == NULL)\r
701 return -1;\r
702 key = entry->key;\r
703 return key != NULL && key != dummy;\r
704}\r
705\r
706static int\r
707set_contains_entry(PySetObject *so, setentry *entry)\r
708{\r
709 PyObject *key;\r
710 setentry *lu_entry;\r
711\r
712 lu_entry = (so->lookup)(so, entry->key, entry->hash);\r
713 if (lu_entry == NULL)\r
714 return -1;\r
715 key = lu_entry->key;\r
716 return key != NULL && key != dummy;\r
717}\r
718\r
719static PyObject *\r
720set_pop(PySetObject *so)\r
721{\r
722 register Py_ssize_t i = 0;\r
723 register setentry *entry;\r
724 PyObject *key;\r
725\r
726 assert (PyAnySet_Check(so));\r
727 if (so->used == 0) {\r
728 PyErr_SetString(PyExc_KeyError, "pop from an empty set");\r
729 return NULL;\r
730 }\r
731\r
732 /* Set entry to "the first" unused or dummy set entry. We abuse\r
733 * the hash field of slot 0 to hold a search finger:\r
734 * If slot 0 has a value, use slot 0.\r
735 * Else slot 0 is being used to hold a search finger,\r
736 * and we use its hash value as the first index to look.\r
737 */\r
738 entry = &so->table[0];\r
739 if (entry->key == NULL || entry->key == dummy) {\r
740 i = entry->hash;\r
741 /* The hash field may be a real hash value, or it may be a\r
742 * legit search finger, or it may be a once-legit search\r
743 * finger that's out of bounds now because it wrapped around\r
744 * or the table shrunk -- simply make sure it's in bounds now.\r
745 */\r
746 if (i > so->mask || i < 1)\r
747 i = 1; /* skip slot 0 */\r
748 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {\r
749 i++;\r
750 if (i > so->mask)\r
751 i = 1;\r
752 }\r
753 }\r
754 key = entry->key;\r
755 Py_INCREF(dummy);\r
756 entry->key = dummy;\r
757 so->used--;\r
758 so->table[0].hash = i + 1; /* next place to start */\r
759 return key;\r
760}\r
761\r
762PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\\r
763Raises KeyError if the set is empty.");\r
764\r
765static int\r
766set_traverse(PySetObject *so, visitproc visit, void *arg)\r
767{\r
768 Py_ssize_t pos = 0;\r
769 setentry *entry;\r
770\r
771 while (set_next(so, &pos, &entry))\r
772 Py_VISIT(entry->key);\r
773 return 0;\r
774}\r
775\r
776static long\r
777frozenset_hash(PyObject *self)\r
778{\r
779 PySetObject *so = (PySetObject *)self;\r
780 long h, hash = 1927868237L;\r
781 setentry *entry;\r
782 Py_ssize_t pos = 0;\r
783\r
784 if (so->hash != -1)\r
785 return so->hash;\r
786\r
787 hash *= PySet_GET_SIZE(self) + 1;\r
788 while (set_next(so, &pos, &entry)) {\r
789 /* Work to increase the bit dispersion for closely spaced hash\r
790 values. The is important because some use cases have many\r
791 combinations of a small number of elements with nearby\r
792 hashes so that many distinct combinations collapse to only\r
793 a handful of distinct hash values. */\r
794 h = entry->hash;\r
795 hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u;\r
796 }\r
797 hash = hash * 69069L + 907133923L;\r
798 if (hash == -1)\r
799 hash = 590923713L;\r
800 so->hash = hash;\r
801 return hash;\r
802}\r
803\r
804/***** Set iterator type ***********************************************/\r
805\r
806typedef struct {\r
807 PyObject_HEAD\r
808 PySetObject *si_set; /* Set to NULL when iterator is exhausted */\r
809 Py_ssize_t si_used;\r
810 Py_ssize_t si_pos;\r
811 Py_ssize_t len;\r
812} setiterobject;\r
813\r
814static void\r
815setiter_dealloc(setiterobject *si)\r
816{\r
817 Py_XDECREF(si->si_set);\r
818 PyObject_GC_Del(si);\r
819}\r
820\r
821static int\r
822setiter_traverse(setiterobject *si, visitproc visit, void *arg)\r
823{\r
824 Py_VISIT(si->si_set);\r
825 return 0;\r
826}\r
827\r
828static PyObject *\r
829setiter_len(setiterobject *si)\r
830{\r
831 Py_ssize_t len = 0;\r
832 if (si->si_set != NULL && si->si_used == si->si_set->used)\r
833 len = si->len;\r
834 return PyInt_FromLong(len);\r
835}\r
836\r
837PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");\r
838\r
839static PyMethodDef setiter_methods[] = {\r
840 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},\r
841 {NULL, NULL} /* sentinel */\r
842};\r
843\r
844static PyObject *setiter_iternext(setiterobject *si)\r
845{\r
846 PyObject *key;\r
847 register Py_ssize_t i, mask;\r
848 register setentry *entry;\r
849 PySetObject *so = si->si_set;\r
850\r
851 if (so == NULL)\r
852 return NULL;\r
853 assert (PyAnySet_Check(so));\r
854\r
855 if (si->si_used != so->used) {\r
856 PyErr_SetString(PyExc_RuntimeError,\r
857 "Set changed size during iteration");\r
858 si->si_used = -1; /* Make this state sticky */\r
859 return NULL;\r
860 }\r
861\r
862 i = si->si_pos;\r
863 assert(i>=0);\r
864 entry = so->table;\r
865 mask = so->mask;\r
866 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))\r
867 i++;\r
868 si->si_pos = i+1;\r
869 if (i > mask)\r
870 goto fail;\r
871 si->len--;\r
872 key = entry[i].key;\r
873 Py_INCREF(key);\r
874 return key;\r
875\r
876fail:\r
877 Py_DECREF(so);\r
878 si->si_set = NULL;\r
879 return NULL;\r
880}\r
881\r
882static PyTypeObject PySetIter_Type = {\r
883 PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
884 "setiterator", /* tp_name */\r
885 sizeof(setiterobject), /* tp_basicsize */\r
886 0, /* tp_itemsize */\r
887 /* methods */\r
888 (destructor)setiter_dealloc, /* tp_dealloc */\r
889 0, /* tp_print */\r
890 0, /* tp_getattr */\r
891 0, /* tp_setattr */\r
892 0, /* tp_compare */\r
893 0, /* tp_repr */\r
894 0, /* tp_as_number */\r
895 0, /* tp_as_sequence */\r
896 0, /* tp_as_mapping */\r
897 0, /* tp_hash */\r
898 0, /* tp_call */\r
899 0, /* tp_str */\r
900 PyObject_GenericGetAttr, /* tp_getattro */\r
901 0, /* tp_setattro */\r
902 0, /* tp_as_buffer */\r
903 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */\r
904 0, /* tp_doc */\r
905 (traverseproc)setiter_traverse, /* tp_traverse */\r
906 0, /* tp_clear */\r
907 0, /* tp_richcompare */\r
908 0, /* tp_weaklistoffset */\r
909 PyObject_SelfIter, /* tp_iter */\r
910 (iternextfunc)setiter_iternext, /* tp_iternext */\r
911 setiter_methods, /* tp_methods */\r
912 0,\r
913};\r
914\r
915static PyObject *\r
916set_iter(PySetObject *so)\r
917{\r
918 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);\r
919 if (si == NULL)\r
920 return NULL;\r
921 Py_INCREF(so);\r
922 si->si_set = so;\r
923 si->si_used = so->used;\r
924 si->si_pos = 0;\r
925 si->len = so->used;\r
926 _PyObject_GC_TRACK(si);\r
927 return (PyObject *)si;\r
928}\r
929\r
930static int\r
931set_update_internal(PySetObject *so, PyObject *other)\r
932{\r
933 PyObject *key, *it;\r
934\r
935 if (PyAnySet_Check(other))\r
936 return set_merge(so, other);\r
937\r
938 if (PyDict_CheckExact(other)) {\r
939 PyObject *value;\r
940 Py_ssize_t pos = 0;\r
941 long hash;\r
942 Py_ssize_t dictsize = PyDict_Size(other);\r
943\r
944 /* Do one big resize at the start, rather than\r
945 * incrementally resizing as we insert new keys. Expect\r
946 * that there will be no (or few) overlapping keys.\r
947 */\r
948 if (dictsize == -1)\r
949 return -1;\r
950 if ((so->fill + dictsize)*3 >= (so->mask+1)*2) {\r
951 if (set_table_resize(so, (so->used + dictsize)*2) != 0)\r
952 return -1;\r
953 }\r
954 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {\r
955 setentry an_entry;\r
956\r
957 an_entry.hash = hash;\r
958 an_entry.key = key;\r
959 if (set_add_entry(so, &an_entry) == -1)\r
960 return -1;\r
961 }\r
962 return 0;\r
963 }\r
964\r
965 it = PyObject_GetIter(other);\r
966 if (it == NULL)\r
967 return -1;\r
968\r
969 while ((key = PyIter_Next(it)) != NULL) {\r
970 if (set_add_key(so, key) == -1) {\r
971 Py_DECREF(it);\r
972 Py_DECREF(key);\r
973 return -1;\r
974 }\r
975 Py_DECREF(key);\r
976 }\r
977 Py_DECREF(it);\r
978 if (PyErr_Occurred())\r
979 return -1;\r
980 return 0;\r
981}\r
982\r
983static PyObject *\r
984set_update(PySetObject *so, PyObject *args)\r
985{\r
986 Py_ssize_t i;\r
987\r
988 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {\r
989 PyObject *other = PyTuple_GET_ITEM(args, i);\r
990 if (set_update_internal(so, other) == -1)\r
991 return NULL;\r
992 }\r
993 Py_RETURN_NONE;\r
994}\r
995\r
996PyDoc_STRVAR(update_doc,\r
997"Update a set with the union of itself and others.");\r
998\r
999static PyObject *\r
1000make_new_set(PyTypeObject *type, PyObject *iterable)\r
1001{\r
1002 register PySetObject *so = NULL;\r
1003\r
1004 if (dummy == NULL) { /* Auto-initialize dummy */\r
1005 dummy = PyString_FromString("<dummy key>");\r
1006 if (dummy == NULL)\r
1007 return NULL;\r
1008 }\r
1009\r
1010 /* create PySetObject structure */\r
1011 if (numfree &&\r
1012 (type == &PySet_Type || type == &PyFrozenSet_Type)) {\r
1013 so = free_list[--numfree];\r
1014 assert (so != NULL && PyAnySet_CheckExact(so));\r
1015 Py_TYPE(so) = type;\r
1016 _Py_NewReference((PyObject *)so);\r
1017 EMPTY_TO_MINSIZE(so);\r
1018 PyObject_GC_Track(so);\r
1019 } else {\r
1020 so = (PySetObject *)type->tp_alloc(type, 0);\r
1021 if (so == NULL)\r
1022 return NULL;\r
1023 /* tp_alloc has already zeroed the structure */\r
1024 assert(so->table == NULL && so->fill == 0 && so->used == 0);\r
1025 INIT_NONZERO_SET_SLOTS(so);\r
1026 }\r
1027\r
1028 so->lookup = set_lookkey_string;\r
1029 so->weakreflist = NULL;\r
1030\r
1031 if (iterable != NULL) {\r
1032 if (set_update_internal(so, iterable) == -1) {\r
1033 Py_DECREF(so);\r
1034 return NULL;\r
1035 }\r
1036 }\r
1037\r
1038 return (PyObject *)so;\r
1039}\r
1040\r
1041/* The empty frozenset is a singleton */\r
1042static PyObject *emptyfrozenset = NULL;\r
1043\r
1044static PyObject *\r
1045frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
1046{\r
1047 PyObject *iterable = NULL, *result;\r
1048\r
1049 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))\r
1050 return NULL;\r
1051\r
1052 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))\r
1053 return NULL;\r
1054\r
1055 if (type != &PyFrozenSet_Type)\r
1056 return make_new_set(type, iterable);\r
1057\r
1058 if (iterable != NULL) {\r
1059 /* frozenset(f) is idempotent */\r
1060 if (PyFrozenSet_CheckExact(iterable)) {\r
1061 Py_INCREF(iterable);\r
1062 return iterable;\r
1063 }\r
1064 result = make_new_set(type, iterable);\r
1065 if (result == NULL || PySet_GET_SIZE(result))\r
1066 return result;\r
1067 Py_DECREF(result);\r
1068 }\r
1069 /* The empty frozenset is a singleton */\r
1070 if (emptyfrozenset == NULL)\r
1071 emptyfrozenset = make_new_set(type, NULL);\r
1072 Py_XINCREF(emptyfrozenset);\r
1073 return emptyfrozenset;\r
1074}\r
1075\r
1076void\r
1077PySet_Fini(void)\r
1078{\r
1079 PySetObject *so;\r
1080\r
1081 while (numfree) {\r
1082 numfree--;\r
1083 so = free_list[numfree];\r
1084 PyObject_GC_Del(so);\r
1085 }\r
1086 Py_CLEAR(dummy);\r
1087 Py_CLEAR(emptyfrozenset);\r
1088}\r
1089\r
1090static PyObject *\r
1091set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
1092{\r
1093 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))\r
1094 return NULL;\r
1095\r
1096 return make_new_set(type, NULL);\r
1097}\r
1098\r
1099/* set_swap_bodies() switches the contents of any two sets by moving their\r
1100 internal data pointers and, if needed, copying the internal smalltables.\r
1101 Semantically equivalent to:\r
1102\r
1103 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t\r
1104\r
1105 The function always succeeds and it leaves both objects in a stable state.\r
1106 Useful for creating temporary frozensets from sets for membership testing\r
1107 in __contains__(), discard(), and remove(). Also useful for operations\r
1108 that update in-place (by allowing an intermediate result to be swapped\r
1109 into one of the original inputs).\r
1110*/\r
1111\r
1112static void\r
1113set_swap_bodies(PySetObject *a, PySetObject *b)\r
1114{\r
1115 Py_ssize_t t;\r
1116 setentry *u;\r
1117 setentry *(*f)(PySetObject *so, PyObject *key, long hash);\r
1118 setentry tab[PySet_MINSIZE];\r
1119 long h;\r
1120\r
1121 t = a->fill; a->fill = b->fill; b->fill = t;\r
1122 t = a->used; a->used = b->used; b->used = t;\r
1123 t = a->mask; a->mask = b->mask; b->mask = t;\r
1124\r
1125 u = a->table;\r
1126 if (a->table == a->smalltable)\r
1127 u = b->smalltable;\r
1128 a->table = b->table;\r
1129 if (b->table == b->smalltable)\r
1130 a->table = a->smalltable;\r
1131 b->table = u;\r
1132\r
1133 f = a->lookup; a->lookup = b->lookup; b->lookup = f;\r
1134\r
1135 if (a->table == a->smalltable || b->table == b->smalltable) {\r
1136 memcpy(tab, a->smalltable, sizeof(tab));\r
1137 memcpy(a->smalltable, b->smalltable, sizeof(tab));\r
1138 memcpy(b->smalltable, tab, sizeof(tab));\r
1139 }\r
1140\r
1141 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&\r
1142 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {\r
1143 h = a->hash; a->hash = b->hash; b->hash = h;\r
1144 } else {\r
1145 a->hash = -1;\r
1146 b->hash = -1;\r
1147 }\r
1148}\r
1149\r
1150static PyObject *\r
1151set_copy(PySetObject *so)\r
1152{\r
1153 return make_new_set(Py_TYPE(so), (PyObject *)so);\r
1154}\r
1155\r
1156static PyObject *\r
1157frozenset_copy(PySetObject *so)\r
1158{\r
1159 if (PyFrozenSet_CheckExact(so)) {\r
1160 Py_INCREF(so);\r
1161 return (PyObject *)so;\r
1162 }\r
1163 return set_copy(so);\r
1164}\r
1165\r
1166PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");\r
1167\r
1168static PyObject *\r
1169set_clear(PySetObject *so)\r
1170{\r
1171 set_clear_internal(so);\r
1172 Py_RETURN_NONE;\r
1173}\r
1174\r
1175PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");\r
1176\r
1177static PyObject *\r
1178set_union(PySetObject *so, PyObject *args)\r
1179{\r
1180 PySetObject *result;\r
1181 PyObject *other;\r
1182 Py_ssize_t i;\r
1183\r
1184 result = (PySetObject *)set_copy(so);\r
1185 if (result == NULL)\r
1186 return NULL;\r
1187\r
1188 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {\r
1189 other = PyTuple_GET_ITEM(args, i);\r
1190 if ((PyObject *)so == other)\r
1191 continue;\r
1192 if (set_update_internal(result, other) == -1) {\r
1193 Py_DECREF(result);\r
1194 return NULL;\r
1195 }\r
1196 }\r
1197 return (PyObject *)result;\r
1198}\r
1199\r
1200PyDoc_STRVAR(union_doc,\r
1201 "Return the union of sets as a new set.\n\\r
1202\n\\r
1203(i.e. all elements that are in either set.)");\r
1204\r
1205static PyObject *\r
1206set_or(PySetObject *so, PyObject *other)\r
1207{\r
1208 PySetObject *result;\r
1209\r
1210 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {\r
1211 Py_INCREF(Py_NotImplemented);\r
1212 return Py_NotImplemented;\r
1213 }\r
1214\r
1215 result = (PySetObject *)set_copy(so);\r
1216 if (result == NULL)\r
1217 return NULL;\r
1218 if ((PyObject *)so == other)\r
1219 return (PyObject *)result;\r
1220 if (set_update_internal(result, other) == -1) {\r
1221 Py_DECREF(result);\r
1222 return NULL;\r
1223 }\r
1224 return (PyObject *)result;\r
1225}\r
1226\r
1227static PyObject *\r
1228set_ior(PySetObject *so, PyObject *other)\r
1229{\r
1230 if (!PyAnySet_Check(other)) {\r
1231 Py_INCREF(Py_NotImplemented);\r
1232 return Py_NotImplemented;\r
1233 }\r
1234 if (set_update_internal(so, other) == -1)\r
1235 return NULL;\r
1236 Py_INCREF(so);\r
1237 return (PyObject *)so;\r
1238}\r
1239\r
1240static PyObject *\r
1241set_intersection(PySetObject *so, PyObject *other)\r
1242{\r
1243 PySetObject *result;\r
1244 PyObject *key, *it, *tmp;\r
1245\r
1246 if ((PyObject *)so == other)\r
1247 return set_copy(so);\r
1248\r
1249 result = (PySetObject *)make_new_set(Py_TYPE(so), NULL);\r
1250 if (result == NULL)\r
1251 return NULL;\r
1252\r
1253 if (PyAnySet_Check(other)) {\r
1254 Py_ssize_t pos = 0;\r
1255 setentry *entry;\r
1256\r
1257 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {\r
1258 tmp = (PyObject *)so;\r
1259 so = (PySetObject *)other;\r
1260 other = tmp;\r
1261 }\r
1262\r
1263 while (set_next((PySetObject *)other, &pos, &entry)) {\r
1264 int rv = set_contains_entry(so, entry);\r
1265 if (rv == -1) {\r
1266 Py_DECREF(result);\r
1267 return NULL;\r
1268 }\r
1269 if (rv) {\r
1270 if (set_add_entry(result, entry) == -1) {\r
1271 Py_DECREF(result);\r
1272 return NULL;\r
1273 }\r
1274 }\r
1275 }\r
1276 return (PyObject *)result;\r
1277 }\r
1278\r
1279 it = PyObject_GetIter(other);\r
1280 if (it == NULL) {\r
1281 Py_DECREF(result);\r
1282 return NULL;\r
1283 }\r
1284\r
1285 while ((key = PyIter_Next(it)) != NULL) {\r
1286 int rv;\r
1287 setentry entry;\r
1288 long hash = PyObject_Hash(key);\r
1289\r
1290 if (hash == -1) {\r
1291 Py_DECREF(it);\r
1292 Py_DECREF(result);\r
1293 Py_DECREF(key);\r
1294 return NULL;\r
1295 }\r
1296 entry.hash = hash;\r
1297 entry.key = key;\r
1298 rv = set_contains_entry(so, &entry);\r
1299 if (rv == -1) {\r
1300 Py_DECREF(it);\r
1301 Py_DECREF(result);\r
1302 Py_DECREF(key);\r
1303 return NULL;\r
1304 }\r
1305 if (rv) {\r
1306 if (set_add_entry(result, &entry) == -1) {\r
1307 Py_DECREF(it);\r
1308 Py_DECREF(result);\r
1309 Py_DECREF(key);\r
1310 return NULL;\r
1311 }\r
1312 }\r
1313 Py_DECREF(key);\r
1314 }\r
1315 Py_DECREF(it);\r
1316 if (PyErr_Occurred()) {\r
1317 Py_DECREF(result);\r
1318 return NULL;\r
1319 }\r
1320 return (PyObject *)result;\r
1321}\r
1322\r
1323static PyObject *\r
1324set_intersection_multi(PySetObject *so, PyObject *args)\r
1325{\r
1326 Py_ssize_t i;\r
1327 PyObject *result = (PyObject *)so;\r
1328\r
1329 if (PyTuple_GET_SIZE(args) == 0)\r
1330 return set_copy(so);\r
1331\r
1332 Py_INCREF(so);\r
1333 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {\r
1334 PyObject *other = PyTuple_GET_ITEM(args, i);\r
1335 PyObject *newresult = set_intersection((PySetObject *)result, other);\r
1336 if (newresult == NULL) {\r
1337 Py_DECREF(result);\r
1338 return NULL;\r
1339 }\r
1340 Py_DECREF(result);\r
1341 result = newresult;\r
1342 }\r
1343 return result;\r
1344}\r
1345\r
1346PyDoc_STRVAR(intersection_doc,\r
1347"Return the intersection of two or more sets as a new set.\n\\r
1348\n\\r
1349(i.e. elements that are common to all of the sets.)");\r
1350\r
1351static PyObject *\r
1352set_intersection_update(PySetObject *so, PyObject *other)\r
1353{\r
1354 PyObject *tmp;\r
1355\r
1356 tmp = set_intersection(so, other);\r
1357 if (tmp == NULL)\r
1358 return NULL;\r
1359 set_swap_bodies(so, (PySetObject *)tmp);\r
1360 Py_DECREF(tmp);\r
1361 Py_RETURN_NONE;\r
1362}\r
1363\r
1364static PyObject *\r
1365set_intersection_update_multi(PySetObject *so, PyObject *args)\r
1366{\r
1367 PyObject *tmp;\r
1368\r
1369 tmp = set_intersection_multi(so, args);\r
1370 if (tmp == NULL)\r
1371 return NULL;\r
1372 set_swap_bodies(so, (PySetObject *)tmp);\r
1373 Py_DECREF(tmp);\r
1374 Py_RETURN_NONE;\r
1375}\r
1376\r
1377PyDoc_STRVAR(intersection_update_doc,\r
1378"Update a set with the intersection of itself and another.");\r
1379\r
1380static PyObject *\r
1381set_and(PySetObject *so, PyObject *other)\r
1382{\r
1383 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {\r
1384 Py_INCREF(Py_NotImplemented);\r
1385 return Py_NotImplemented;\r
1386 }\r
1387 return set_intersection(so, other);\r
1388}\r
1389\r
1390static PyObject *\r
1391set_iand(PySetObject *so, PyObject *other)\r
1392{\r
1393 PyObject *result;\r
1394\r
1395 if (!PyAnySet_Check(other)) {\r
1396 Py_INCREF(Py_NotImplemented);\r
1397 return Py_NotImplemented;\r
1398 }\r
1399 result = set_intersection_update(so, other);\r
1400 if (result == NULL)\r
1401 return NULL;\r
1402 Py_DECREF(result);\r
1403 Py_INCREF(so);\r
1404 return (PyObject *)so;\r
1405}\r
1406\r
1407static PyObject *\r
1408set_isdisjoint(PySetObject *so, PyObject *other)\r
1409{\r
1410 PyObject *key, *it, *tmp;\r
1411\r
1412 if ((PyObject *)so == other) {\r
1413 if (PySet_GET_SIZE(so) == 0)\r
1414 Py_RETURN_TRUE;\r
1415 else\r
1416 Py_RETURN_FALSE;\r
1417 }\r
1418\r
1419 if (PyAnySet_CheckExact(other)) {\r
1420 Py_ssize_t pos = 0;\r
1421 setentry *entry;\r
1422\r
1423 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {\r
1424 tmp = (PyObject *)so;\r
1425 so = (PySetObject *)other;\r
1426 other = tmp;\r
1427 }\r
1428 while (set_next((PySetObject *)other, &pos, &entry)) {\r
1429 int rv = set_contains_entry(so, entry);\r
1430 if (rv == -1)\r
1431 return NULL;\r
1432 if (rv)\r
1433 Py_RETURN_FALSE;\r
1434 }\r
1435 Py_RETURN_TRUE;\r
1436 }\r
1437\r
1438 it = PyObject_GetIter(other);\r
1439 if (it == NULL)\r
1440 return NULL;\r
1441\r
1442 while ((key = PyIter_Next(it)) != NULL) {\r
1443 int rv;\r
1444 setentry entry;\r
1445 long hash = PyObject_Hash(key);\r
1446\r
1447 if (hash == -1) {\r
1448 Py_DECREF(key);\r
1449 Py_DECREF(it);\r
1450 return NULL;\r
1451 }\r
1452 entry.hash = hash;\r
1453 entry.key = key;\r
1454 rv = set_contains_entry(so, &entry);\r
1455 Py_DECREF(key);\r
1456 if (rv == -1) {\r
1457 Py_DECREF(it);\r
1458 return NULL;\r
1459 }\r
1460 if (rv) {\r
1461 Py_DECREF(it);\r
1462 Py_RETURN_FALSE;\r
1463 }\r
1464 }\r
1465 Py_DECREF(it);\r
1466 if (PyErr_Occurred())\r
1467 return NULL;\r
1468 Py_RETURN_TRUE;\r
1469}\r
1470\r
1471PyDoc_STRVAR(isdisjoint_doc,\r
1472"Return True if two sets have a null intersection.");\r
1473\r
1474static int\r
1475set_difference_update_internal(PySetObject *so, PyObject *other)\r
1476{\r
1477 if ((PyObject *)so == other)\r
1478 return set_clear_internal(so);\r
1479\r
1480 if (PyAnySet_Check(other)) {\r
1481 setentry *entry;\r
1482 Py_ssize_t pos = 0;\r
1483\r
1484 while (set_next((PySetObject *)other, &pos, &entry))\r
1485 if (set_discard_entry(so, entry) == -1)\r
1486 return -1;\r
1487 } else {\r
1488 PyObject *key, *it;\r
1489 it = PyObject_GetIter(other);\r
1490 if (it == NULL)\r
1491 return -1;\r
1492\r
1493 while ((key = PyIter_Next(it)) != NULL) {\r
1494 if (set_discard_key(so, key) == -1) {\r
1495 Py_DECREF(it);\r
1496 Py_DECREF(key);\r
1497 return -1;\r
1498 }\r
1499 Py_DECREF(key);\r
1500 }\r
1501 Py_DECREF(it);\r
1502 if (PyErr_Occurred())\r
1503 return -1;\r
1504 }\r
1505 /* If more than 1/5 are dummies, then resize them away. */\r
1506 if ((so->fill - so->used) * 5 < so->mask)\r
1507 return 0;\r
1508 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);\r
1509}\r
1510\r
1511static PyObject *\r
1512set_difference_update(PySetObject *so, PyObject *args)\r
1513{\r
1514 Py_ssize_t i;\r
1515\r
1516 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {\r
1517 PyObject *other = PyTuple_GET_ITEM(args, i);\r
1518 if (set_difference_update_internal(so, other) == -1)\r
1519 return NULL;\r
1520 }\r
1521 Py_RETURN_NONE;\r
1522}\r
1523\r
1524PyDoc_STRVAR(difference_update_doc,\r
1525"Remove all elements of another set from this set.");\r
1526\r
1527static PyObject *\r
1528set_difference(PySetObject *so, PyObject *other)\r
1529{\r
1530 PyObject *result;\r
1531 setentry *entry;\r
1532 Py_ssize_t pos = 0;\r
1533\r
1534 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {\r
1535 result = set_copy(so);\r
1536 if (result == NULL)\r
1537 return NULL;\r
1538 if (set_difference_update_internal((PySetObject *)result, other) != -1)\r
1539 return result;\r
1540 Py_DECREF(result);\r
1541 return NULL;\r
1542 }\r
1543\r
1544 result = make_new_set(Py_TYPE(so), NULL);\r
1545 if (result == NULL)\r
1546 return NULL;\r
1547\r
1548 if (PyDict_CheckExact(other)) {\r
1549 while (set_next(so, &pos, &entry)) {\r
1550 setentry entrycopy;\r
1551 entrycopy.hash = entry->hash;\r
1552 entrycopy.key = entry->key;\r
1553 if (!_PyDict_Contains(other, entry->key, entry->hash)) {\r
1554 if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {\r
1555 Py_DECREF(result);\r
1556 return NULL;\r
1557 }\r
1558 }\r
1559 }\r
1560 return result;\r
1561 }\r
1562\r
1563 while (set_next(so, &pos, &entry)) {\r
1564 int rv = set_contains_entry((PySetObject *)other, entry);\r
1565 if (rv == -1) {\r
1566 Py_DECREF(result);\r
1567 return NULL;\r
1568 }\r
1569 if (!rv) {\r
1570 if (set_add_entry((PySetObject *)result, entry) == -1) {\r
1571 Py_DECREF(result);\r
1572 return NULL;\r
1573 }\r
1574 }\r
1575 }\r
1576 return result;\r
1577}\r
1578\r
1579static PyObject *\r
1580set_difference_multi(PySetObject *so, PyObject *args)\r
1581{\r
1582 Py_ssize_t i;\r
1583 PyObject *result, *other;\r
1584\r
1585 if (PyTuple_GET_SIZE(args) == 0)\r
1586 return set_copy(so);\r
1587\r
1588 other = PyTuple_GET_ITEM(args, 0);\r
1589 result = set_difference(so, other);\r
1590 if (result == NULL)\r
1591 return NULL;\r
1592\r
1593 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {\r
1594 other = PyTuple_GET_ITEM(args, i);\r
1595 if (set_difference_update_internal((PySetObject *)result, other) == -1) {\r
1596 Py_DECREF(result);\r
1597 return NULL;\r
1598 }\r
1599 }\r
1600 return result;\r
1601}\r
1602\r
1603PyDoc_STRVAR(difference_doc,\r
1604"Return the difference of two or more sets as a new set.\n\\r
1605\n\\r
1606(i.e. all elements that are in this set but not the others.)");\r
1607static PyObject *\r
1608set_sub(PySetObject *so, PyObject *other)\r
1609{\r
1610 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {\r
1611 Py_INCREF(Py_NotImplemented);\r
1612 return Py_NotImplemented;\r
1613 }\r
1614 return set_difference(so, other);\r
1615}\r
1616\r
1617static PyObject *\r
1618set_isub(PySetObject *so, PyObject *other)\r
1619{\r
1620 if (!PyAnySet_Check(other)) {\r
1621 Py_INCREF(Py_NotImplemented);\r
1622 return Py_NotImplemented;\r
1623 }\r
1624 if (set_difference_update_internal(so, other) == -1)\r
1625 return NULL;\r
1626 Py_INCREF(so);\r
1627 return (PyObject *)so;\r
1628}\r
1629\r
1630static PyObject *\r
1631set_symmetric_difference_update(PySetObject *so, PyObject *other)\r
1632{\r
1633 PySetObject *otherset;\r
1634 PyObject *key;\r
1635 Py_ssize_t pos = 0;\r
1636 setentry *entry;\r
1637\r
1638 if ((PyObject *)so == other)\r
1639 return set_clear(so);\r
1640\r
1641 if (PyDict_CheckExact(other)) {\r
1642 PyObject *value;\r
1643 int rv;\r
1644 long hash;\r
1645 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {\r
1646 setentry an_entry;\r
1647\r
1648 Py_INCREF(key);\r
1649 an_entry.hash = hash;\r
1650 an_entry.key = key;\r
1651\r
1652 rv = set_discard_entry(so, &an_entry);\r
1653 if (rv == -1) {\r
1654 Py_DECREF(key);\r
1655 return NULL;\r
1656 }\r
1657 if (rv == DISCARD_NOTFOUND) {\r
1658 if (set_add_entry(so, &an_entry) == -1) {\r
1659 Py_DECREF(key);\r
1660 return NULL;\r
1661 }\r
1662 }\r
1663 Py_DECREF(key);\r
1664 }\r
1665 Py_RETURN_NONE;\r
1666 }\r
1667\r
1668 if (PyAnySet_Check(other)) {\r
1669 Py_INCREF(other);\r
1670 otherset = (PySetObject *)other;\r
1671 } else {\r
1672 otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);\r
1673 if (otherset == NULL)\r
1674 return NULL;\r
1675 }\r
1676\r
1677 while (set_next(otherset, &pos, &entry)) {\r
1678 int rv = set_discard_entry(so, entry);\r
1679 if (rv == -1) {\r
1680 Py_DECREF(otherset);\r
1681 return NULL;\r
1682 }\r
1683 if (rv == DISCARD_NOTFOUND) {\r
1684 if (set_add_entry(so, entry) == -1) {\r
1685 Py_DECREF(otherset);\r
1686 return NULL;\r
1687 }\r
1688 }\r
1689 }\r
1690 Py_DECREF(otherset);\r
1691 Py_RETURN_NONE;\r
1692}\r
1693\r
1694PyDoc_STRVAR(symmetric_difference_update_doc,\r
1695"Update a set with the symmetric difference of itself and another.");\r
1696\r
1697static PyObject *\r
1698set_symmetric_difference(PySetObject *so, PyObject *other)\r
1699{\r
1700 PyObject *rv;\r
1701 PySetObject *otherset;\r
1702\r
1703 otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);\r
1704 if (otherset == NULL)\r
1705 return NULL;\r
1706 rv = set_symmetric_difference_update(otherset, (PyObject *)so);\r
1707 if (rv == NULL)\r
1708 return NULL;\r
1709 Py_DECREF(rv);\r
1710 return (PyObject *)otherset;\r
1711}\r
1712\r
1713PyDoc_STRVAR(symmetric_difference_doc,\r
1714"Return the symmetric difference of two sets as a new set.\n\\r
1715\n\\r
1716(i.e. all elements that are in exactly one of the sets.)");\r
1717\r
1718static PyObject *\r
1719set_xor(PySetObject *so, PyObject *other)\r
1720{\r
1721 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {\r
1722 Py_INCREF(Py_NotImplemented);\r
1723 return Py_NotImplemented;\r
1724 }\r
1725 return set_symmetric_difference(so, other);\r
1726}\r
1727\r
1728static PyObject *\r
1729set_ixor(PySetObject *so, PyObject *other)\r
1730{\r
1731 PyObject *result;\r
1732\r
1733 if (!PyAnySet_Check(other)) {\r
1734 Py_INCREF(Py_NotImplemented);\r
1735 return Py_NotImplemented;\r
1736 }\r
1737 result = set_symmetric_difference_update(so, other);\r
1738 if (result == NULL)\r
1739 return NULL;\r
1740 Py_DECREF(result);\r
1741 Py_INCREF(so);\r
1742 return (PyObject *)so;\r
1743}\r
1744\r
1745static PyObject *\r
1746set_issubset(PySetObject *so, PyObject *other)\r
1747{\r
1748 setentry *entry;\r
1749 Py_ssize_t pos = 0;\r
1750\r
1751 if (!PyAnySet_Check(other)) {\r
1752 PyObject *tmp, *result;\r
1753 tmp = make_new_set(&PySet_Type, other);\r
1754 if (tmp == NULL)\r
1755 return NULL;\r
1756 result = set_issubset(so, tmp);\r
1757 Py_DECREF(tmp);\r
1758 return result;\r
1759 }\r
1760 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))\r
1761 Py_RETURN_FALSE;\r
1762\r
1763 while (set_next(so, &pos, &entry)) {\r
1764 int rv = set_contains_entry((PySetObject *)other, entry);\r
1765 if (rv == -1)\r
1766 return NULL;\r
1767 if (!rv)\r
1768 Py_RETURN_FALSE;\r
1769 }\r
1770 Py_RETURN_TRUE;\r
1771}\r
1772\r
1773PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");\r
1774\r
1775static PyObject *\r
1776set_issuperset(PySetObject *so, PyObject *other)\r
1777{\r
1778 PyObject *tmp, *result;\r
1779\r
1780 if (!PyAnySet_Check(other)) {\r
1781 tmp = make_new_set(&PySet_Type, other);\r
1782 if (tmp == NULL)\r
1783 return NULL;\r
1784 result = set_issuperset(so, tmp);\r
1785 Py_DECREF(tmp);\r
1786 return result;\r
1787 }\r
1788 return set_issubset((PySetObject *)other, (PyObject *)so);\r
1789}\r
1790\r
1791PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");\r
1792\r
1793static PyObject *\r
1794set_richcompare(PySetObject *v, PyObject *w, int op)\r
1795{\r
1796 PyObject *r1, *r2;\r
1797\r
1798 if(!PyAnySet_Check(w)) {\r
1799 Py_INCREF(Py_NotImplemented);\r
1800 return Py_NotImplemented;\r
1801 }\r
1802 switch (op) {\r
1803 case Py_EQ:\r
1804 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))\r
1805 Py_RETURN_FALSE;\r
1806 if (v->hash != -1 &&\r
1807 ((PySetObject *)w)->hash != -1 &&\r
1808 v->hash != ((PySetObject *)w)->hash)\r
1809 Py_RETURN_FALSE;\r
1810 return set_issubset(v, w);\r
1811 case Py_NE:\r
1812 r1 = set_richcompare(v, w, Py_EQ);\r
1813 if (r1 == NULL)\r
1814 return NULL;\r
1815 r2 = PyBool_FromLong(PyObject_Not(r1));\r
1816 Py_DECREF(r1);\r
1817 return r2;\r
1818 case Py_LE:\r
1819 return set_issubset(v, w);\r
1820 case Py_GE:\r
1821 return set_issuperset(v, w);\r
1822 case Py_LT:\r
1823 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))\r
1824 Py_RETURN_FALSE;\r
1825 return set_issubset(v, w);\r
1826 case Py_GT:\r
1827 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))\r
1828 Py_RETURN_FALSE;\r
1829 return set_issuperset(v, w);\r
1830 }\r
1831 Py_INCREF(Py_NotImplemented);\r
1832 return Py_NotImplemented;\r
1833}\r
1834\r
1835static int\r
1836set_nocmp(PyObject *self, PyObject *other)\r
1837{\r
1838 PyErr_SetString(PyExc_TypeError, "cannot compare sets using cmp()");\r
1839 return -1;\r
1840}\r
1841\r
1842static PyObject *\r
1843set_add(PySetObject *so, PyObject *key)\r
1844{\r
1845 if (set_add_key(so, key) == -1)\r
1846 return NULL;\r
1847 Py_RETURN_NONE;\r
1848}\r
1849\r
1850PyDoc_STRVAR(add_doc,\r
1851"Add an element to a set.\n\\r
1852\n\\r
1853This has no effect if the element is already present.");\r
1854\r
1855static int\r
1856set_contains(PySetObject *so, PyObject *key)\r
1857{\r
1858 PyObject *tmpkey;\r
1859 int rv;\r
1860\r
1861 rv = set_contains_key(so, key);\r
1862 if (rv == -1) {\r
1863 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))\r
1864 return -1;\r
1865 PyErr_Clear();\r
1866 tmpkey = make_new_set(&PyFrozenSet_Type, key);\r
1867 if (tmpkey == NULL)\r
1868 return -1;\r
1869 rv = set_contains_key(so, tmpkey);\r
1870 Py_DECREF(tmpkey);\r
1871 }\r
1872 return rv;\r
1873}\r
1874\r
1875static PyObject *\r
1876set_direct_contains(PySetObject *so, PyObject *key)\r
1877{\r
1878 long result;\r
1879\r
1880 result = set_contains(so, key);\r
1881 if (result == -1)\r
1882 return NULL;\r
1883 return PyBool_FromLong(result);\r
1884}\r
1885\r
1886PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");\r
1887\r
1888static PyObject *\r
1889set_remove(PySetObject *so, PyObject *key)\r
1890{\r
1891 PyObject *tmpkey;\r
1892 int rv;\r
1893\r
1894 rv = set_discard_key(so, key);\r
1895 if (rv == -1) {\r
1896 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))\r
1897 return NULL;\r
1898 PyErr_Clear();\r
1899 tmpkey = make_new_set(&PyFrozenSet_Type, key);\r
1900 if (tmpkey == NULL)\r
1901 return NULL;\r
1902 rv = set_discard_key(so, tmpkey);\r
1903 Py_DECREF(tmpkey);\r
1904 if (rv == -1)\r
1905 return NULL;\r
1906 }\r
1907\r
1908 if (rv == DISCARD_NOTFOUND) {\r
1909 set_key_error(key);\r
1910 return NULL;\r
1911 }\r
1912 Py_RETURN_NONE;\r
1913}\r
1914\r
1915PyDoc_STRVAR(remove_doc,\r
1916"Remove an element from a set; it must be a member.\n\\r
1917\n\\r
1918If the element is not a member, raise a KeyError.");\r
1919\r
1920static PyObject *\r
1921set_discard(PySetObject *so, PyObject *key)\r
1922{\r
1923 PyObject *tmpkey;\r
1924 int rv;\r
1925\r
1926 rv = set_discard_key(so, key);\r
1927 if (rv == -1) {\r
1928 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))\r
1929 return NULL;\r
1930 PyErr_Clear();\r
1931 tmpkey = make_new_set(&PyFrozenSet_Type, key);\r
1932 if (tmpkey == NULL)\r
1933 return NULL;\r
1934 rv = set_discard_key(so, tmpkey);\r
1935 Py_DECREF(tmpkey);\r
1936 if (rv == -1)\r
1937 return NULL;\r
1938 }\r
1939 Py_RETURN_NONE;\r
1940}\r
1941\r
1942PyDoc_STRVAR(discard_doc,\r
1943"Remove an element from a set if it is a member.\n\\r
1944\n\\r
1945If the element is not a member, do nothing.");\r
1946\r
1947static PyObject *\r
1948set_reduce(PySetObject *so)\r
1949{\r
1950 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;\r
1951\r
1952 keys = PySequence_List((PyObject *)so);\r
1953 if (keys == NULL)\r
1954 goto done;\r
1955 args = PyTuple_Pack(1, keys);\r
1956 if (args == NULL)\r
1957 goto done;\r
1958 dict = PyObject_GetAttrString((PyObject *)so, "__dict__");\r
1959 if (dict == NULL) {\r
1960 PyErr_Clear();\r
1961 dict = Py_None;\r
1962 Py_INCREF(dict);\r
1963 }\r
1964 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);\r
1965done:\r
1966 Py_XDECREF(args);\r
1967 Py_XDECREF(keys);\r
1968 Py_XDECREF(dict);\r
1969 return result;\r
1970}\r
1971\r
1972PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");\r
1973\r
1974static PyObject *\r
1975set_sizeof(PySetObject *so)\r
1976{\r
1977 Py_ssize_t res;\r
1978\r
1979 res = sizeof(PySetObject);\r
1980 if (so->table != so->smalltable)\r
1981 res = res + (so->mask + 1) * sizeof(setentry);\r
1982 return PyInt_FromSsize_t(res);\r
1983}\r
1984\r
1985PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");\r
1986static int\r
1987set_init(PySetObject *self, PyObject *args, PyObject *kwds)\r
1988{\r
1989 PyObject *iterable = NULL;\r
1990\r
1991 if (!PyAnySet_Check(self))\r
1992 return -1;\r
1993 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))\r
1994 return -1;\r
1995 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))\r
1996 return -1;\r
1997 set_clear_internal(self);\r
1998 self->hash = -1;\r
1999 if (iterable == NULL)\r
2000 return 0;\r
2001 return set_update_internal(self, iterable);\r
2002}\r
2003\r
2004static PySequenceMethods set_as_sequence = {\r
2005 set_len, /* sq_length */\r
2006 0, /* sq_concat */\r
2007 0, /* sq_repeat */\r
2008 0, /* sq_item */\r
2009 0, /* sq_slice */\r
2010 0, /* sq_ass_item */\r
2011 0, /* sq_ass_slice */\r
2012 (objobjproc)set_contains, /* sq_contains */\r
2013};\r
2014\r
2015/* set object ********************************************************/\r
2016\r
2017#ifdef Py_DEBUG\r
2018static PyObject *test_c_api(PySetObject *so);\r
2019\r
2020PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\\r
2021All is well if assertions don't fail.");\r
2022#endif\r
2023\r
2024static PyMethodDef set_methods[] = {\r
2025 {"add", (PyCFunction)set_add, METH_O,\r
2026 add_doc},\r
2027 {"clear", (PyCFunction)set_clear, METH_NOARGS,\r
2028 clear_doc},\r
2029 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,\r
2030 contains_doc},\r
2031 {"copy", (PyCFunction)set_copy, METH_NOARGS,\r
2032 copy_doc},\r
2033 {"discard", (PyCFunction)set_discard, METH_O,\r
2034 discard_doc},\r
2035 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,\r
2036 difference_doc},\r
2037 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,\r
2038 difference_update_doc},\r
2039 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,\r
2040 intersection_doc},\r
2041 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,\r
2042 intersection_update_doc},\r
2043 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,\r
2044 isdisjoint_doc},\r
2045 {"issubset", (PyCFunction)set_issubset, METH_O,\r
2046 issubset_doc},\r
2047 {"issuperset", (PyCFunction)set_issuperset, METH_O,\r
2048 issuperset_doc},\r
2049 {"pop", (PyCFunction)set_pop, METH_NOARGS,\r
2050 pop_doc},\r
2051 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,\r
2052 reduce_doc},\r
2053 {"remove", (PyCFunction)set_remove, METH_O,\r
2054 remove_doc},\r
2055 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,\r
2056 sizeof_doc},\r
2057 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,\r
2058 symmetric_difference_doc},\r
2059 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,\r
2060 symmetric_difference_update_doc},\r
2061#ifdef Py_DEBUG\r
2062 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,\r
2063 test_c_api_doc},\r
2064#endif\r
2065 {"union", (PyCFunction)set_union, METH_VARARGS,\r
2066 union_doc},\r
2067 {"update", (PyCFunction)set_update, METH_VARARGS,\r
2068 update_doc},\r
2069 {NULL, NULL} /* sentinel */\r
2070};\r
2071\r
2072static PyNumberMethods set_as_number = {\r
2073 0, /*nb_add*/\r
2074 (binaryfunc)set_sub, /*nb_subtract*/\r
2075 0, /*nb_multiply*/\r
2076 0, /*nb_divide*/\r
2077 0, /*nb_remainder*/\r
2078 0, /*nb_divmod*/\r
2079 0, /*nb_power*/\r
2080 0, /*nb_negative*/\r
2081 0, /*nb_positive*/\r
2082 0, /*nb_absolute*/\r
2083 0, /*nb_nonzero*/\r
2084 0, /*nb_invert*/\r
2085 0, /*nb_lshift*/\r
2086 0, /*nb_rshift*/\r
2087 (binaryfunc)set_and, /*nb_and*/\r
2088 (binaryfunc)set_xor, /*nb_xor*/\r
2089 (binaryfunc)set_or, /*nb_or*/\r
2090 0, /*nb_coerce*/\r
2091 0, /*nb_int*/\r
2092 0, /*nb_long*/\r
2093 0, /*nb_float*/\r
2094 0, /*nb_oct*/\r
2095 0, /*nb_hex*/\r
2096 0, /*nb_inplace_add*/\r
2097 (binaryfunc)set_isub, /*nb_inplace_subtract*/\r
2098 0, /*nb_inplace_multiply*/\r
2099 0, /*nb_inplace_divide*/\r
2100 0, /*nb_inplace_remainder*/\r
2101 0, /*nb_inplace_power*/\r
2102 0, /*nb_inplace_lshift*/\r
2103 0, /*nb_inplace_rshift*/\r
2104 (binaryfunc)set_iand, /*nb_inplace_and*/\r
2105 (binaryfunc)set_ixor, /*nb_inplace_xor*/\r
2106 (binaryfunc)set_ior, /*nb_inplace_or*/\r
2107};\r
2108\r
2109PyDoc_STRVAR(set_doc,\r
2110"set() -> new empty set object\n\\r
2111set(iterable) -> new set object\n\\r
2112\n\\r
2113Build an unordered collection of unique elements.");\r
2114\r
2115PyTypeObject PySet_Type = {\r
2116 PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
2117 "set", /* tp_name */\r
2118 sizeof(PySetObject), /* tp_basicsize */\r
2119 0, /* tp_itemsize */\r
2120 /* methods */\r
2121 (destructor)set_dealloc, /* tp_dealloc */\r
2122 (printfunc)set_tp_print, /* tp_print */\r
2123 0, /* tp_getattr */\r
2124 0, /* tp_setattr */\r
2125 set_nocmp, /* tp_compare */\r
2126 (reprfunc)set_repr, /* tp_repr */\r
2127 &set_as_number, /* tp_as_number */\r
2128 &set_as_sequence, /* tp_as_sequence */\r
2129 0, /* tp_as_mapping */\r
2130 (hashfunc)PyObject_HashNotImplemented, /* tp_hash */\r
2131 0, /* tp_call */\r
2132 0, /* tp_str */\r
2133 PyObject_GenericGetAttr, /* tp_getattro */\r
2134 0, /* tp_setattro */\r
2135 0, /* tp_as_buffer */\r
2136 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |\r
2137 Py_TPFLAGS_BASETYPE, /* tp_flags */\r
2138 set_doc, /* tp_doc */\r
2139 (traverseproc)set_traverse, /* tp_traverse */\r
2140 (inquiry)set_clear_internal, /* tp_clear */\r
2141 (richcmpfunc)set_richcompare, /* tp_richcompare */\r
2142 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */\r
2143 (getiterfunc)set_iter, /* tp_iter */\r
2144 0, /* tp_iternext */\r
2145 set_methods, /* tp_methods */\r
2146 0, /* tp_members */\r
2147 0, /* tp_getset */\r
2148 0, /* tp_base */\r
2149 0, /* tp_dict */\r
2150 0, /* tp_descr_get */\r
2151 0, /* tp_descr_set */\r
2152 0, /* tp_dictoffset */\r
2153 (initproc)set_init, /* tp_init */\r
2154 PyType_GenericAlloc, /* tp_alloc */\r
2155 set_new, /* tp_new */\r
2156 PyObject_GC_Del, /* tp_free */\r
2157};\r
2158\r
2159/* frozenset object ********************************************************/\r
2160\r
2161\r
2162static PyMethodDef frozenset_methods[] = {\r
2163 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,\r
2164 contains_doc},\r
2165 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,\r
2166 copy_doc},\r
2167 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,\r
2168 difference_doc},\r
2169 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,\r
2170 intersection_doc},\r
2171 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,\r
2172 isdisjoint_doc},\r
2173 {"issubset", (PyCFunction)set_issubset, METH_O,\r
2174 issubset_doc},\r
2175 {"issuperset", (PyCFunction)set_issuperset, METH_O,\r
2176 issuperset_doc},\r
2177 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,\r
2178 reduce_doc},\r
2179 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,\r
2180 sizeof_doc},\r
2181 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,\r
2182 symmetric_difference_doc},\r
2183 {"union", (PyCFunction)set_union, METH_VARARGS,\r
2184 union_doc},\r
2185 {NULL, NULL} /* sentinel */\r
2186};\r
2187\r
2188static PyNumberMethods frozenset_as_number = {\r
2189 0, /*nb_add*/\r
2190 (binaryfunc)set_sub, /*nb_subtract*/\r
2191 0, /*nb_multiply*/\r
2192 0, /*nb_divide*/\r
2193 0, /*nb_remainder*/\r
2194 0, /*nb_divmod*/\r
2195 0, /*nb_power*/\r
2196 0, /*nb_negative*/\r
2197 0, /*nb_positive*/\r
2198 0, /*nb_absolute*/\r
2199 0, /*nb_nonzero*/\r
2200 0, /*nb_invert*/\r
2201 0, /*nb_lshift*/\r
2202 0, /*nb_rshift*/\r
2203 (binaryfunc)set_and, /*nb_and*/\r
2204 (binaryfunc)set_xor, /*nb_xor*/\r
2205 (binaryfunc)set_or, /*nb_or*/\r
2206};\r
2207\r
2208PyDoc_STRVAR(frozenset_doc,\r
2209"frozenset() -> empty frozenset object\n\\r
2210frozenset(iterable) -> frozenset object\n\\r
2211\n\\r
2212Build an immutable unordered collection of unique elements.");\r
2213\r
2214PyTypeObject PyFrozenSet_Type = {\r
2215 PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
2216 "frozenset", /* tp_name */\r
2217 sizeof(PySetObject), /* tp_basicsize */\r
2218 0, /* tp_itemsize */\r
2219 /* methods */\r
2220 (destructor)set_dealloc, /* tp_dealloc */\r
2221 (printfunc)set_tp_print, /* tp_print */\r
2222 0, /* tp_getattr */\r
2223 0, /* tp_setattr */\r
2224 set_nocmp, /* tp_compare */\r
2225 (reprfunc)set_repr, /* tp_repr */\r
2226 &frozenset_as_number, /* tp_as_number */\r
2227 &set_as_sequence, /* tp_as_sequence */\r
2228 0, /* tp_as_mapping */\r
2229 frozenset_hash, /* tp_hash */\r
2230 0, /* tp_call */\r
2231 0, /* tp_str */\r
2232 PyObject_GenericGetAttr, /* tp_getattro */\r
2233 0, /* tp_setattro */\r
2234 0, /* tp_as_buffer */\r
2235 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |\r
2236 Py_TPFLAGS_BASETYPE, /* tp_flags */\r
2237 frozenset_doc, /* tp_doc */\r
2238 (traverseproc)set_traverse, /* tp_traverse */\r
2239 (inquiry)set_clear_internal, /* tp_clear */\r
2240 (richcmpfunc)set_richcompare, /* tp_richcompare */\r
2241 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */\r
2242 (getiterfunc)set_iter, /* tp_iter */\r
2243 0, /* tp_iternext */\r
2244 frozenset_methods, /* tp_methods */\r
2245 0, /* tp_members */\r
2246 0, /* tp_getset */\r
2247 0, /* tp_base */\r
2248 0, /* tp_dict */\r
2249 0, /* tp_descr_get */\r
2250 0, /* tp_descr_set */\r
2251 0, /* tp_dictoffset */\r
2252 0, /* tp_init */\r
2253 PyType_GenericAlloc, /* tp_alloc */\r
2254 frozenset_new, /* tp_new */\r
2255 PyObject_GC_Del, /* tp_free */\r
2256};\r
2257\r
2258\r
2259/***** C API functions *************************************************/\r
2260\r
2261PyObject *\r
2262PySet_New(PyObject *iterable)\r
2263{\r
2264 return make_new_set(&PySet_Type, iterable);\r
2265}\r
2266\r
2267PyObject *\r
2268PyFrozenSet_New(PyObject *iterable)\r
2269{\r
2270 return make_new_set(&PyFrozenSet_Type, iterable);\r
2271}\r
2272\r
2273Py_ssize_t\r
2274PySet_Size(PyObject *anyset)\r
2275{\r
2276 if (!PyAnySet_Check(anyset)) {\r
2277 PyErr_BadInternalCall();\r
2278 return -1;\r
2279 }\r
2280 return PySet_GET_SIZE(anyset);\r
2281}\r
2282\r
2283int\r
2284PySet_Clear(PyObject *set)\r
2285{\r
2286 if (!PySet_Check(set)) {\r
2287 PyErr_BadInternalCall();\r
2288 return -1;\r
2289 }\r
2290 return set_clear_internal((PySetObject *)set);\r
2291}\r
2292\r
2293int\r
2294PySet_Contains(PyObject *anyset, PyObject *key)\r
2295{\r
2296 if (!PyAnySet_Check(anyset)) {\r
2297 PyErr_BadInternalCall();\r
2298 return -1;\r
2299 }\r
2300 return set_contains_key((PySetObject *)anyset, key);\r
2301}\r
2302\r
2303int\r
2304PySet_Discard(PyObject *set, PyObject *key)\r
2305{\r
2306 if (!PySet_Check(set)) {\r
2307 PyErr_BadInternalCall();\r
2308 return -1;\r
2309 }\r
2310 return set_discard_key((PySetObject *)set, key);\r
2311}\r
2312\r
2313int\r
2314PySet_Add(PyObject *anyset, PyObject *key)\r
2315{\r
2316 if (!PySet_Check(anyset) &&\r
2317 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {\r
2318 PyErr_BadInternalCall();\r
2319 return -1;\r
2320 }\r
2321 return set_add_key((PySetObject *)anyset, key);\r
2322}\r
2323\r
2324int\r
2325_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key)\r
2326{\r
2327 setentry *entry_ptr;\r
2328\r
2329 if (!PyAnySet_Check(set)) {\r
2330 PyErr_BadInternalCall();\r
2331 return -1;\r
2332 }\r
2333 if (set_next((PySetObject *)set, pos, &entry_ptr) == 0)\r
2334 return 0;\r
2335 *key = entry_ptr->key;\r
2336 return 1;\r
2337}\r
2338\r
2339int\r
2340_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)\r
2341{\r
2342 setentry *entry;\r
2343\r
2344 if (!PyAnySet_Check(set)) {\r
2345 PyErr_BadInternalCall();\r
2346 return -1;\r
2347 }\r
2348 if (set_next((PySetObject *)set, pos, &entry) == 0)\r
2349 return 0;\r
2350 *key = entry->key;\r
2351 *hash = entry->hash;\r
2352 return 1;\r
2353}\r
2354\r
2355PyObject *\r
2356PySet_Pop(PyObject *set)\r
2357{\r
2358 if (!PySet_Check(set)) {\r
2359 PyErr_BadInternalCall();\r
2360 return NULL;\r
2361 }\r
2362 return set_pop((PySetObject *)set);\r
2363}\r
2364\r
2365int\r
2366_PySet_Update(PyObject *set, PyObject *iterable)\r
2367{\r
2368 if (!PySet_Check(set)) {\r
2369 PyErr_BadInternalCall();\r
2370 return -1;\r
2371 }\r
2372 return set_update_internal((PySetObject *)set, iterable);\r
2373}\r
2374\r
2375#ifdef Py_DEBUG\r
2376\r
2377/* Test code to be called with any three element set.\r
2378 Returns True and original set is restored. */\r
2379\r
2380#define assertRaises(call_return_value, exception) \\r
2381 do { \\r
2382 assert(call_return_value); \\r
2383 assert(PyErr_ExceptionMatches(exception)); \\r
2384 PyErr_Clear(); \\r
2385 } while(0)\r
2386\r
2387static PyObject *\r
2388test_c_api(PySetObject *so)\r
2389{\r
2390 Py_ssize_t count;\r
2391 char *s;\r
2392 Py_ssize_t i;\r
2393 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x;\r
2394 PyObject *ob = (PyObject *)so;\r
2395 PyObject *str;\r
2396\r
2397 /* Verify preconditions */\r
2398 assert(PyAnySet_Check(ob));\r
2399 assert(PyAnySet_CheckExact(ob));\r
2400 assert(!PyFrozenSet_CheckExact(ob));\r
2401\r
2402 /* so.clear(); so |= set("abc"); */\r
2403 str = PyString_FromString("abc");\r
2404 if (str == NULL)\r
2405 return NULL;\r
2406 set_clear_internal(so);\r
2407 if (set_update_internal(so, str) == -1) {\r
2408 Py_DECREF(str);\r
2409 return NULL;\r
2410 }\r
2411 Py_DECREF(str);\r
2412\r
2413 /* Exercise type/size checks */\r
2414 assert(PySet_Size(ob) == 3);\r
2415 assert(PySet_GET_SIZE(ob) == 3);\r
2416\r
2417 /* Raise TypeError for non-iterable constructor arguments */\r
2418 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);\r
2419 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);\r
2420\r
2421 /* Raise TypeError for unhashable key */\r
2422 dup = PySet_New(ob);\r
2423 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);\r
2424 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);\r
2425 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);\r
2426\r
2427 /* Exercise successful pop, contains, add, and discard */\r
2428 elem = PySet_Pop(ob);\r
2429 assert(PySet_Contains(ob, elem) == 0);\r
2430 assert(PySet_GET_SIZE(ob) == 2);\r
2431 assert(PySet_Add(ob, elem) == 0);\r
2432 assert(PySet_Contains(ob, elem) == 1);\r
2433 assert(PySet_GET_SIZE(ob) == 3);\r
2434 assert(PySet_Discard(ob, elem) == 1);\r
2435 assert(PySet_GET_SIZE(ob) == 2);\r
2436 assert(PySet_Discard(ob, elem) == 0);\r
2437 assert(PySet_GET_SIZE(ob) == 2);\r
2438\r
2439 /* Exercise clear */\r
2440 dup2 = PySet_New(dup);\r
2441 assert(PySet_Clear(dup2) == 0);\r
2442 assert(PySet_Size(dup2) == 0);\r
2443 Py_DECREF(dup2);\r
2444\r
2445 /* Raise SystemError on clear or update of frozen set */\r
2446 f = PyFrozenSet_New(dup);\r
2447 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);\r
2448 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);\r
2449 assert(PySet_Add(f, elem) == 0);\r
2450 Py_INCREF(f);\r
2451 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);\r
2452 Py_DECREF(f);\r
2453 Py_DECREF(f);\r
2454\r
2455 /* Exercise direct iteration */\r
2456 i = 0, count = 0;\r
2457 while (_PySet_Next((PyObject *)dup, &i, &x)) {\r
2458 s = PyString_AsString(x);\r
2459 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));\r
2460 count++;\r
2461 }\r
2462 assert(count == 3);\r
2463\r
2464 /* Exercise updates */\r
2465 dup2 = PySet_New(NULL);\r
2466 assert(_PySet_Update(dup2, dup) == 0);\r
2467 assert(PySet_Size(dup2) == 3);\r
2468 assert(_PySet_Update(dup2, dup) == 0);\r
2469 assert(PySet_Size(dup2) == 3);\r
2470 Py_DECREF(dup2);\r
2471\r
2472 /* Raise SystemError when self argument is not a set or frozenset. */\r
2473 t = PyTuple_New(0);\r
2474 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);\r
2475 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);\r
2476 Py_DECREF(t);\r
2477\r
2478 /* Raise SystemError when self argument is not a set. */\r
2479 f = PyFrozenSet_New(dup);\r
2480 assert(PySet_Size(f) == 3);\r
2481 assert(PyFrozenSet_CheckExact(f));\r
2482 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);\r
2483 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);\r
2484 Py_DECREF(f);\r
2485\r
2486 /* Raise KeyError when popping from an empty set */\r
2487 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);\r
2488 Py_DECREF(ob);\r
2489 assert(PySet_GET_SIZE(ob) == 0);\r
2490 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);\r
2491\r
2492 /* Restore the set from the copy using the PyNumber API */\r
2493 assert(PyNumber_InPlaceOr(ob, dup) == ob);\r
2494 Py_DECREF(ob);\r
2495\r
2496 /* Verify constructors accept NULL arguments */\r
2497 f = PySet_New(NULL);\r
2498 assert(f != NULL);\r
2499 assert(PySet_GET_SIZE(f) == 0);\r
2500 Py_DECREF(f);\r
2501 f = PyFrozenSet_New(NULL);\r
2502 assert(f != NULL);\r
2503 assert(PyFrozenSet_CheckExact(f));\r
2504 assert(PySet_GET_SIZE(f) == 0);\r
2505 Py_DECREF(f);\r
2506\r
2507 Py_DECREF(elem);\r
2508 Py_DECREF(dup);\r
2509 Py_RETURN_TRUE;\r
2510}\r
2511\r
2512#undef assertRaises\r
2513\r
2514#endif\r