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