blob: 88d5640635f2880569345ce817bbb5144a8b79bc [file] [log] [blame]
Raymond Hettingera690a992003-11-16 16:17:49 +00001#include "Python.h"
2
3/* set object implementation
4 written and maintained by Raymond D. Hettinger <python@rcn.com>
5 derived from sets.py written by Greg V. Wilson, Alex Martelli,
6 Guido van Rossum, Raymond Hettinger, and Tim Peters.
7
8 Copyright (c) 2003 Python Software Foundation.
9 All rights reserved.
10*/
11
Raymond Hettingera690a992003-11-16 16:17:49 +000012static PyObject *
13make_new_set(PyTypeObject *type, PyObject *iterable)
14{
15 PyObject *data;
16 PyObject *it = NULL;
17 PyObject *item;
18 PySetObject *so;
19
20 /* Get iterator. */
21 if (iterable != NULL) {
22 it = PyObject_GetIter(iterable);
23 if (it == NULL)
24 return NULL;
25 }
26
27 data = PyDict_New();
28 if (data == NULL) {
29 Py_DECREF(it);
30 return NULL;
31 }
32
33 while (it != NULL && (item = PyIter_Next(it)) != NULL) {
34 if (PyDict_SetItem(data, item, Py_True) == -1) {
35 Py_DECREF(it);
36 Py_DECREF(data);
37 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +000038 return NULL;
39 }
40 Py_DECREF(item);
41 }
42 Py_XDECREF(it);
43 if (PyErr_Occurred()) {
44 Py_DECREF(data);
45 return NULL;
46 }
47
48 /* create PySetObject structure */
49 so = (PySetObject *)type->tp_alloc(type, 0);
50 if (so == NULL) {
51 Py_DECREF(data);
52 return NULL;
53 }
54 so->data = data;
55 so->hash = -1;
56
57 return (PyObject *)so;
58}
59
60static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +000061frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +000062{
63 PyObject *iterable = NULL;
64
65 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
66 return NULL;
67 return make_new_set(type, iterable);
68}
69
Raymond Hettinger50a4bb32003-11-17 16:42:33 +000070static PyObject *
71set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
72{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +000073 return make_new_set(type, NULL);
74}
75
Raymond Hettingera690a992003-11-16 16:17:49 +000076static void
77set_dealloc(PySetObject *so)
78{
79 PyObject_GC_UnTrack(so);
80 Py_XDECREF(so->data);
81 so->ob_type->tp_free(so);
82}
83
84static int
85set_traverse(PySetObject *so, visitproc visit, void *arg)
86{
87 if (so->data)
88 return visit(so->data, arg);
89 return 0;
90}
91
92static PyObject *
93set_iter(PySetObject *so)
94{
95 return PyObject_GetIter(so->data);
96}
97
98static int
99set_len(PySetObject *so)
100{
101 return PyDict_Size(so->data);
102}
103
104static int
105set_contains(PySetObject *so, PyObject *key)
106{
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000107 return PySequence_Contains(so->data, key);
Raymond Hettingera690a992003-11-16 16:17:49 +0000108}
109
110static PyObject *
111set_copy(PySetObject *so)
112{
113 PyObject *data;
114 PySetObject *newso;
115
116 data = PyDict_Copy(so->data);
117 if (data == NULL)
118 return NULL;
119
120 newso = (PySetObject *)(so->ob_type->tp_alloc(so->ob_type, 0));
121 if (newso == NULL) {
122 Py_DECREF(data);
123 return NULL;
124 }
125 newso->data = data;
126 newso->hash = so->hash;
127 return (PyObject *)newso;
128}
129
130PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
131
132static PyObject *
133set_union(PySetObject *so, PyObject *other)
134{
135 PySetObject *result;
136 PyObject *item, *data, *it;
137
138 result = (PySetObject *)set_copy(so);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000139 if (result == NULL)
140 return NULL;
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000141
142 if (PyAnySet_Check(other)) {
143 if (PyDict_Merge(result->data, ((PySetObject *)other)->data, 0) == -1) {
144 Py_DECREF(result);
145 return NULL;
146 }
147 return (PyObject *)result;
148 }
149
Raymond Hettingera690a992003-11-16 16:17:49 +0000150 it = PyObject_GetIter(other);
151 if (it == NULL) {
152 Py_DECREF(result);
153 return NULL;
154 }
155 data = result->data;
156 while ((item = PyIter_Next(it)) != NULL) {
157 if (PyDict_SetItem(data, item, Py_True) == -1) {
158 Py_DECREF(it);
159 Py_DECREF(result);
160 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000161 return NULL;
162 }
163 Py_DECREF(item);
164 }
165 Py_DECREF(it);
166 if (PyErr_Occurred()) {
167 Py_DECREF(result);
168 return NULL;
169 }
170 return (PyObject *)result;
171}
172
173PyDoc_STRVAR(union_doc,
174 "Return the union of two sets as a new set.\n\
175\n\
176(i.e. all elements that are in either set.)");
177
178static PyObject *
179set_union_update(PySetObject *so, PyObject *other)
180{
181 PyObject *item, *data, *it;
182
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000183 if (PyAnySet_Check(other)) {
184 if (PyDict_Merge(so->data, ((PySetObject *)other)->data, 0) == -1)
185 return NULL;
186 Py_INCREF(so);
187 return (PyObject *)so;
188 }
189
Raymond Hettingera690a992003-11-16 16:17:49 +0000190 it = PyObject_GetIter(other);
191 if (it == NULL)
192 return NULL;
193 data = so->data;
194
195 while ((item = PyIter_Next(it)) != NULL) {
196 if (PyDict_SetItem(data, item, Py_True) == -1) {
197 Py_DECREF(it);
198 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000199 return NULL;
200 }
201 Py_DECREF(item);
202 }
203 Py_DECREF(it);
204 if (PyErr_Occurred())
205 return NULL;
206 Py_RETURN_NONE;
207}
208
209PyDoc_STRVAR(union_update_doc,
210"Update a set with the union of itself and another.");
211
212static PyObject *
213set_or(PySetObject *so, PyObject *other)
214{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000215 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000216 Py_INCREF(Py_NotImplemented);
217 return Py_NotImplemented;
218 }
219 return set_union(so, other);
220}
221
222static PyObject *
223set_ior(PySetObject *so, PyObject *other)
224{
225 PyObject *result;
226
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000227 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000228 Py_INCREF(Py_NotImplemented);
229 return Py_NotImplemented;
230 }
231 result = set_union_update(so, other);
232 if (result == NULL)
233 return NULL;
234 Py_DECREF(result);
235 Py_INCREF(so);
236 return (PyObject *)so;
237}
238
239static PyObject *
240set_intersection(PySetObject *so, PyObject *other)
241{
242 PySetObject *result;
243 PyObject *item, *selfdata, *tgtdata, *it;
244
245 result = (PySetObject *)make_new_set(so->ob_type, NULL);
246 if (result == NULL)
247 return NULL;
248
249 it = PyObject_GetIter(other);
250 if (it == NULL) {
251 Py_DECREF(result);
252 return NULL;
253 }
254
255 selfdata = so->data;
256 tgtdata = result->data;
257 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000258 if (PySequence_Contains(selfdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000259 if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
260 Py_DECREF(it);
261 Py_DECREF(result);
262 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000263 return NULL;
264 }
265 }
266 Py_DECREF(item);
267 }
268 Py_DECREF(it);
269 if (PyErr_Occurred()) {
270 Py_DECREF(result);
271 return NULL;
272 }
273 return (PyObject *)result;
274}
275
276PyDoc_STRVAR(intersection_doc,
277"Return the intersection of two sets as a new set.\n\
278\n\
279(i.e. all elements that are in both sets.)");
280
281static PyObject *
282set_intersection_update(PySetObject *so, PyObject *other)
283{
284 PyObject *item, *selfdata, *it, *newdict, *tmp;
285
286 newdict = PyDict_New();
287 if (newdict == NULL)
288 return newdict;
289
290 it = PyObject_GetIter(other);
291 if (it == NULL) {
292 Py_DECREF(newdict);
293 return NULL;
294 }
295
296 selfdata = so->data;
297 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000298 if (PySequence_Contains(selfdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000299 if (PyDict_SetItem(newdict, item, Py_True) == -1) {
300 Py_DECREF(newdict);
301 Py_DECREF(it);
302 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000303 return NULL;
304 }
305 }
306 Py_DECREF(item);
307 }
308 Py_DECREF(it);
309 if (PyErr_Occurred()) {
310 Py_DECREF(newdict);
311 return NULL;
312 }
313 tmp = so->data;
314 so->data = newdict;
315 Py_DECREF(tmp);
316 Py_RETURN_NONE;
317}
318
319PyDoc_STRVAR(intersection_update_doc,
320"Update a set with the intersection of itself and another.");
321
322static PyObject *
323set_and(PySetObject *so, PyObject *other)
324{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000325 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000326 Py_INCREF(Py_NotImplemented);
327 return Py_NotImplemented;
328 }
329 return set_intersection(so, other);
330}
331
332static PyObject *
333set_iand(PySetObject *so, PyObject *other)
334{
335 PyObject *result;
336
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000337 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000338 Py_INCREF(Py_NotImplemented);
339 return Py_NotImplemented;
340 }
341 result = set_intersection_update(so, other);
342 if (result == NULL)
343 return NULL;
344 Py_DECREF(result);
345 Py_INCREF(so);
346 return (PyObject *)so;
347}
348
349static PyObject *
350set_difference(PySetObject *so, PyObject *other)
351{
352 PySetObject *result;
353 PyObject *item, *tgtdata, *it;
354
355 result = (PySetObject *)set_copy(so);
356 if (result == NULL)
357 return NULL;
358
359 it = PyObject_GetIter(other);
360 if (it == NULL) {
361 Py_DECREF(result);
362 return NULL;
363 }
364
365 tgtdata = result->data;
366 while ((item = PyIter_Next(it)) != NULL) {
367 if (PyDict_DelItem(tgtdata, item) == -1) {
368 if (PyErr_ExceptionMatches(PyExc_KeyError))
369 PyErr_Clear();
370 else {
371 Py_DECREF(it);
372 Py_DECREF(result);
373 Py_DECREF(item);
374 return NULL;
375 }
376 }
377 Py_DECREF(item);
378 }
379 Py_DECREF(it);
380 if (PyErr_Occurred()) {
381 Py_DECREF(result);
382 return NULL;
383 }
384 return (PyObject *)result;
385}
386
387PyDoc_STRVAR(difference_doc,
388"Return the difference of two sets as a new set.\n\
389\n\
390(i.e. all elements that are in this set but not the other.)");
391
392static PyObject *
393set_difference_update(PySetObject *so, PyObject *other)
394{
395 PyObject *item, *tgtdata, *it;
396
397 it = PyObject_GetIter(other);
398 if (it == NULL)
399 return NULL;
400
401 tgtdata = so->data;
402 while ((item = PyIter_Next(it)) != NULL) {
403 if (PyDict_DelItem(tgtdata, item) == -1) {
404 if (PyErr_ExceptionMatches(PyExc_KeyError))
405 PyErr_Clear();
406 else {
407 Py_DECREF(it);
408 Py_DECREF(item);
409 return NULL;
410 }
411 }
412 Py_DECREF(item);
413 }
414 Py_DECREF(it);
415 if (PyErr_Occurred())
416 return NULL;
417 Py_RETURN_NONE;
418}
419
420PyDoc_STRVAR(difference_update_doc,
421"Remove all elements of another set from this set.");
422
423static PyObject *
424set_sub(PySetObject *so, PyObject *other)
425{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000426 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000427 Py_INCREF(Py_NotImplemented);
428 return Py_NotImplemented;
429 }
430 return set_difference(so, other);
431}
432
433static PyObject *
434set_isub(PySetObject *so, PyObject *other)
435{
436 PyObject *result;
437
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000438 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000439 Py_INCREF(Py_NotImplemented);
440 return Py_NotImplemented;
441 }
442 result = set_difference_update(so, other);
443 if (result == NULL)
444 return NULL;
445 Py_DECREF(result);
446 Py_INCREF(so);
447 return (PyObject *)so;
448}
449
450static PyObject *
451set_symmetric_difference(PySetObject *so, PyObject *other)
452{
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000453 PySetObject *result, *otherset=NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000454 PyObject *item, *selfdata, *otherdata, *tgtdata, *it;
455
456 selfdata = so->data;
457
458 result = (PySetObject *)set_copy(so);
459 if (result == NULL)
460 return NULL;
461 tgtdata = result->data;
462
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000463 if (PyDict_Check(other))
464 otherdata = other;
465 else if (PyAnySet_Check(other))
466 otherdata = ((PySetObject *)other)->data;
467 else {
468 otherset = (PySetObject *)make_new_set(so->ob_type, other);
469 if (otherset == NULL) {
470 Py_DECREF(result);
471 return NULL;
472 }
473 otherdata = otherset->data;
474 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000475
476 it = PyObject_GetIter(otherdata);
477 if (it == NULL) {
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000478 Py_XDECREF(otherset);
Raymond Hettingera690a992003-11-16 16:17:49 +0000479 Py_DECREF(result);
480 return NULL;
481 }
482
483 while ((item = PyIter_Next(it)) != NULL) {
484 if (PyDict_DelItem(tgtdata, item) == -1) {
485 PyErr_Clear();
486 if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
487 Py_DECREF(it);
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000488 Py_XDECREF(otherset);
Raymond Hettingera690a992003-11-16 16:17:49 +0000489 Py_DECREF(result);
490 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000491 return NULL;
492 }
493 }
494 Py_DECREF(item);
495 }
496 Py_DECREF(it);
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000497 Py_XDECREF(otherset);
Raymond Hettingera690a992003-11-16 16:17:49 +0000498 if (PyErr_Occurred()) {
499 Py_DECREF(result);
500 return NULL;
501 }
502 return (PyObject *)result;
503}
504
505PyDoc_STRVAR(symmetric_difference_doc,
506"Return the symmetric difference of two sets as a new set.\n\
507\n\
508(i.e. all elements that are in exactly one of the sets.)");
509
510static PyObject *
511set_symmetric_difference_update(PySetObject *so, PyObject *other)
512{
513 PyObject *item, *selfdata, *it, *otherdata;
514 PySetObject *otherset = NULL;
515
516 selfdata = so->data;
517
518 if (PyDict_Check(other))
519 otherdata = other;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000520 else if (PyAnySet_Check(other))
Raymond Hettingera690a992003-11-16 16:17:49 +0000521 otherdata = ((PySetObject *)other)->data;
522 else {
523 otherset = (PySetObject *)make_new_set(so->ob_type, other);
524 if (otherset == NULL)
525 return NULL;
526 otherdata = otherset->data;
527 }
528
529 it = PyObject_GetIter(otherdata);
530 if (it == NULL)
531 return NULL;
532
533 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000534 if (PySequence_Contains(selfdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000535 if (PyDict_DelItem(selfdata, item) == -1) {
536 Py_XDECREF(otherset);
537 Py_DECREF(it);
538 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000539 return NULL;
540 }
541 } else {
542 if (PyDict_SetItem(selfdata, item, Py_True) == -1) {
543 Py_XDECREF(otherset);
544 Py_DECREF(it);
545 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000546 return NULL;
547 }
548 }
549 Py_DECREF(item);
550 }
551 Py_XDECREF(otherset);
552 Py_DECREF(it);
553 if (PyErr_Occurred())
554 return NULL;
555 Py_RETURN_NONE;
556}
557
558PyDoc_STRVAR(symmetric_difference_update_doc,
559"Update a set with the symmetric difference of itself and another.");
560
561static PyObject *
562set_xor(PySetObject *so, PyObject *other)
563{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000564 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000565 Py_INCREF(Py_NotImplemented);
566 return Py_NotImplemented;
567 }
568 return set_symmetric_difference(so, other);
569}
570
571static PyObject *
572set_ixor(PySetObject *so, PyObject *other)
573{
574 PyObject *result;
575
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000576 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000577 Py_INCREF(Py_NotImplemented);
578 return Py_NotImplemented;
579 }
580 result = set_symmetric_difference_update(so, other);
581 if (result == NULL)
582 return NULL;
583 Py_DECREF(result);
584 Py_INCREF(so);
585 return (PyObject *)so;
586}
587
588static PyObject *
589set_issubset(PySetObject *so, PyObject *other)
590{
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000591 PyObject *otherdata, *it, *item, *tmp, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +0000592
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000593 if (!PyAnySet_Check(other)) {
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000594 tmp = make_new_set(&PySet_Type, other);
595 if (tmp == NULL)
596 return NULL;
597 result = set_issubset(so, tmp);
598 Py_DECREF(tmp);
599 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +0000600 }
601 if (set_len(so) > set_len((PySetObject *)other))
602 Py_RETURN_FALSE;
603
604 it = PyObject_GetIter(so->data);
605 if (it == NULL)
606 return NULL;
607
608 otherdata = ((PySetObject *)other)->data;
609 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000610 if (!PySequence_Contains(otherdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000611 Py_DECREF(it);
612 Py_DECREF(item);
613 Py_RETURN_FALSE;
614 }
615 Py_DECREF(item);
616 }
617 Py_DECREF(it);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000618 if (PyErr_Occurred())
619 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000620 Py_RETURN_TRUE;
621}
622
623PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
624
625static PyObject *
626set_issuperset(PySetObject *so, PyObject *other)
627{
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000628 PyObject *tmp, *result;
629
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000630 if (!PyAnySet_Check(other)) {
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000631 tmp = make_new_set(&PySet_Type, other);
632 if (tmp == NULL)
633 return NULL;
634 result = set_issuperset(so, tmp);
635 Py_DECREF(tmp);
636 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +0000637 }
638 return set_issubset((PySetObject *)other, (PyObject *)so);
639}
640
641PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
642
643static long
644set_nohash(PyObject *self)
645{
646 PyErr_SetString(PyExc_TypeError, "set objects are unhashable");
647 return -1;
648}
649
650static int
651set_nocmp(PyObject *self)
652{
653 PyErr_SetString(PyExc_TypeError, "cannot compare sets using cmp()");
654 return -1;
655}
656
657static long
658frozenset_hash(PyObject *self)
659{
660 PyObject *it, *item;
661 PySetObject *so = (PySetObject *)self;
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000662 long hash = 0, x;
Raymond Hettingera690a992003-11-16 16:17:49 +0000663
664 if (so->hash != -1)
665 return so->hash;
666
667 it = PyObject_GetIter(((PySetObject *)so)->data);
668 if (it == NULL)
669 return -1;
670
671 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger82d73dd2003-11-20 22:54:33 +0000672 x = PyObject_Hash(item);
673 /* Applying x*(x+1) breaks-up linear relationships so that
674 h(1) ^ h(2) will be less likely to coincide with hash(3).
675 Multiplying by a large prime increases the dispersion
676 between consecutive hashes. Adding one bit from the
677 original restores the one bit lost during the multiply
678 (all the products are even numbers). */
679 hash ^= (x * (x+1) * 3644798167) | (x&1);
Raymond Hettingera690a992003-11-16 16:17:49 +0000680 Py_DECREF(item);
681 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000682 Py_DECREF(it);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000683 if (PyErr_Occurred())
684 return -1;
685 so->hash = hash;
Raymond Hettingera690a992003-11-16 16:17:49 +0000686 return hash;
687}
688
689static PyObject *
690set_richcompare(PySetObject *v, PyObject *w, int op)
691{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000692 if(!PyAnySet_Check(w)) {
693 if (op == Py_EQ)
694 Py_RETURN_FALSE;
695 if (op == Py_NE)
696 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +0000697 PyErr_SetString(PyExc_TypeError, "can only compare to a set");
698 return NULL;
699 }
700 switch (op) {
701 case Py_EQ:
702 case Py_NE:
703 return PyObject_RichCompare(((PySetObject *)v)->data,
704 ((PySetObject *)w)->data, op);
705 case Py_LE:
706 return set_issubset((PySetObject *)v, w);
707 case Py_GE:
708 return set_issuperset((PySetObject *)v, w);
709 case Py_LT:
710 if (set_len(v) >= set_len((PySetObject *)w))
711 Py_RETURN_FALSE;
712 return set_issubset((PySetObject *)v, w);
713 case Py_GT:
714 if (set_len(v) <= set_len((PySetObject *)w))
715 Py_RETURN_FALSE;
716 return set_issuperset((PySetObject *)v, w);
717 }
718 Py_INCREF(Py_NotImplemented);
719 return Py_NotImplemented;
720}
721
722static PyObject *
723set_repr(PySetObject *so)
724{
725 PyObject *keys, *result, *listrepr;
726
727 keys = PyDict_Keys(so->data);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000728 if (keys == NULL)
729 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000730 listrepr = PyObject_Repr(keys);
731 Py_DECREF(keys);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000732 if (listrepr == NULL)
733 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000734
735 result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
736 PyString_AS_STRING(listrepr));
737 Py_DECREF(listrepr);
738 return result;
739}
740
741static int
742set_tp_print(PySetObject *so, FILE *fp, int flags)
743{
744 PyObject *it, *item;
745 int firstpass=1;
746
747 it = PyObject_GetIter(so->data);
748 if (it == NULL)
749 return -1;
750 fprintf(fp, "%s([", so->ob_type->tp_name);
751
752 while ((item = PyIter_Next(it)) != NULL) {
753 if (firstpass == 1)
754 firstpass = 0;
755 else
Raymond Hettingere2c277a2003-11-16 16:36:58 +0000756 fprintf(fp, ", ");
Raymond Hettingera690a992003-11-16 16:17:49 +0000757 if (PyObject_Print(item, fp, 0) != 0) {
758 Py_DECREF(it);
759 Py_DECREF(item);
760 return -1;
761 }
762 Py_DECREF(item);
763 }
764 Py_DECREF(it);
765 fprintf(fp, "])");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000766 if (PyErr_Occurred())
767 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000768 return 0;
769}
770
771static PyObject *
772set_clear(PySetObject *so)
773{
774 PyDict_Clear(so->data);
775 so->hash = -1;
776 Py_INCREF(Py_None);
777 return Py_None;
778}
779
780PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
781
782static int
783set_tp_clear(PySetObject *so)
784{
785 PyDict_Clear(so->data);
786 so->hash = -1;
787 return 0;
788}
789
790static PyObject *
791set_add(PySetObject *so, PyObject *item)
792{
793 if (PyDict_SetItem(so->data, item, Py_True) == -1)
794 return NULL;
795 Py_INCREF(Py_None);
796 return Py_None;
797}
798
799PyDoc_STRVAR(add_doc,
800"Add an element to a set.\n\
801\n\
802This has no effect if the element is already present.");
803
804static PyObject *
805set_remove(PySetObject *so, PyObject *item)
806{
807 if (PyDict_DelItem(so->data, item) == -1)
808 return NULL;
809 Py_INCREF(Py_None);
810 return Py_None;
811}
812
813PyDoc_STRVAR(remove_doc,
814"Remove an element from a set; it must be a member.\n\
815\n\
816If the element is not a member, raise a KeyError.");
817
818static PyObject *
819set_discard(PySetObject *so, PyObject *item)
820{
Guido van Rossumb61982b2003-11-18 19:27:19 +0000821 if (PyDict_DelItem(so->data, item) == -1) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000822 if (PyErr_ExceptionMatches(PyExc_KeyError))
823 PyErr_Clear();
824 else
825 return NULL;
Guido van Rossumb61982b2003-11-18 19:27:19 +0000826 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000827 Py_INCREF(Py_None);
828 return Py_None;
829}
830
831PyDoc_STRVAR(discard_doc,
832"Remove an element from a set if it is a member.\n\
833\n\
834If the element is not a member, do nothing.");
835
836static PyObject *
837set_pop(PySetObject *so)
838{
839 PyObject *key, *value;
840 int pos = 0;
841
842 if (!PyDict_Next(so->data, &pos, &key, &value)) {
843 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
844 return NULL;
845 }
846 Py_INCREF(key);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000847 if (PyDict_DelItem(so->data, key) == -1) {
848 Py_DECREF(key);
849 return NULL;
850 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000851 return key;
852}
853
854PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.");
855
856static PyObject *
857set_reduce(PySetObject *so)
858{
859 PyObject *keys=NULL, *args=NULL, *result=NULL;
860
861 keys = PyDict_Keys(so->data);
862 if (keys == NULL)
863 goto done;
864 args = PyTuple_Pack(1, keys);
865 if (args == NULL)
866 goto done;
867 result = PyTuple_Pack(2, so->ob_type, args);
868done:
869 Py_XDECREF(args);
870 Py_XDECREF(keys);
871 return result;
872}
873
874PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
875
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000876static int
877set_init(PySetObject *self, PyObject *args, PyObject *kwds)
878{
879 PyObject *iterable = NULL;
880 PyObject *result;
881
882 if (!PyAnySet_Check(self))
883 return -1;
884 if (!PyArg_UnpackTuple(args, self->ob_type->tp_name, 0, 1, &iterable))
885 return -1;
886 PyDict_Clear(self->data);
887 self->hash = -1;
888 if (iterable == NULL)
889 return 0;
890 result = set_union_update(self, iterable);
891 if (result != NULL) {
892 Py_DECREF(result);
893 return 0;
894 }
895 return -1;
896}
897
Raymond Hettingera690a992003-11-16 16:17:49 +0000898static PySequenceMethods set_as_sequence = {
899 (inquiry)set_len, /* sq_length */
900 0, /* sq_concat */
901 0, /* sq_repeat */
902 0, /* sq_item */
903 0, /* sq_slice */
904 0, /* sq_ass_item */
905 0, /* sq_ass_slice */
906 (objobjproc)set_contains, /* sq_contains */
907};
908
909/* set object ********************************************************/
910
911static PyMethodDef set_methods[] = {
912 {"add", (PyCFunction)set_add, METH_O,
913 add_doc},
914 {"clear", (PyCFunction)set_clear, METH_NOARGS,
915 clear_doc},
916 {"copy", (PyCFunction)set_copy, METH_NOARGS,
917 copy_doc},
918 {"__copy__", (PyCFunction)set_copy, METH_NOARGS,
919 copy_doc},
920 {"discard", (PyCFunction)set_discard, METH_O,
921 discard_doc},
922 {"difference", (PyCFunction)set_difference, METH_O,
923 difference_doc},
924 {"difference_update", (PyCFunction)set_difference_update, METH_O,
925 difference_update_doc},
926 {"intersection",(PyCFunction)set_intersection, METH_O,
927 intersection_doc},
928 {"intersection_update",(PyCFunction)set_intersection_update, METH_O,
929 intersection_update_doc},
930 {"issubset", (PyCFunction)set_issubset, METH_O,
931 issubset_doc},
932 {"issuperset", (PyCFunction)set_issuperset, METH_O,
933 issuperset_doc},
934 {"pop", (PyCFunction)set_pop, METH_NOARGS,
935 pop_doc},
936 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
937 reduce_doc},
938 {"remove", (PyCFunction)set_remove, METH_O,
939 remove_doc},
940 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
941 symmetric_difference_doc},
942 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
943 symmetric_difference_update_doc},
944 {"union", (PyCFunction)set_union, METH_O,
945 union_doc},
946 {"union_update",(PyCFunction)set_union_update, METH_O,
947 union_update_doc},
948 {NULL, NULL} /* sentinel */
949};
950
951static PyNumberMethods set_as_number = {
952 0, /*nb_add*/
953 (binaryfunc)set_sub, /*nb_subtract*/
954 0, /*nb_multiply*/
955 0, /*nb_divide*/
956 0, /*nb_remainder*/
957 0, /*nb_divmod*/
958 0, /*nb_power*/
959 0, /*nb_negative*/
960 0, /*nb_positive*/
961 0, /*nb_absolute*/
962 0, /*nb_nonzero*/
963 0, /*nb_invert*/
964 0, /*nb_lshift*/
965 0, /*nb_rshift*/
966 (binaryfunc)set_and, /*nb_and*/
967 (binaryfunc)set_xor, /*nb_xor*/
968 (binaryfunc)set_or, /*nb_or*/
969 0, /*nb_coerce*/
970 0, /*nb_int*/
971 0, /*nb_long*/
972 0, /*nb_float*/
973 0, /*nb_oct*/
974 0, /*nb_hex*/
975 0, /*nb_inplace_add*/
976 (binaryfunc)set_isub, /*nb_inplace_subtract*/
977 0, /*nb_inplace_multiply*/
978 0, /*nb_inplace_divide*/
979 0, /*nb_inplace_remainder*/
980 0, /*nb_inplace_power*/
981 0, /*nb_inplace_lshift*/
982 0, /*nb_inplace_rshift*/
983 (binaryfunc)set_iand, /*nb_inplace_and*/
984 (binaryfunc)set_ixor, /*nb_inplace_xor*/
985 (binaryfunc)set_ior, /*nb_inplace_or*/
986};
987
988PyDoc_STRVAR(set_doc,
989"set(iterable) --> set object\n\
990\n\
991Build an unordered collection.");
992
993PyTypeObject PySet_Type = {
994 PyObject_HEAD_INIT(&PyType_Type)
995 0, /* ob_size */
996 "set", /* tp_name */
997 sizeof(PySetObject), /* tp_basicsize */
998 0, /* tp_itemsize */
999 /* methods */
1000 (destructor)set_dealloc, /* tp_dealloc */
1001 (printfunc)set_tp_print, /* tp_print */
1002 0, /* tp_getattr */
1003 0, /* tp_setattr */
1004 (cmpfunc)set_nocmp, /* tp_compare */
1005 (reprfunc)set_repr, /* tp_repr */
1006 &set_as_number, /* tp_as_number */
1007 &set_as_sequence, /* tp_as_sequence */
1008 0, /* tp_as_mapping */
1009 set_nohash, /* tp_hash */
1010 0, /* tp_call */
1011 0, /* tp_str */
1012 PyObject_GenericGetAttr, /* tp_getattro */
1013 0, /* tp_setattro */
1014 0, /* tp_as_buffer */
1015 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
1016 Py_TPFLAGS_BASETYPE, /* tp_flags */
1017 set_doc, /* tp_doc */
1018 (traverseproc)set_traverse, /* tp_traverse */
1019 (inquiry)set_tp_clear, /* tp_clear */
1020 (richcmpfunc)set_richcompare, /* tp_richcompare */
1021 0, /* tp_weaklistoffset */
1022 (getiterfunc)set_iter, /* tp_iter */
1023 0, /* tp_iternext */
1024 set_methods, /* tp_methods */
1025 0, /* tp_members */
1026 0, /* tp_getset */
1027 0, /* tp_base */
1028 0, /* tp_dict */
1029 0, /* tp_descr_get */
1030 0, /* tp_descr_set */
1031 0, /* tp_dictoffset */
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001032 (initproc)set_init, /* tp_init */
Raymond Hettingera690a992003-11-16 16:17:49 +00001033 PyType_GenericAlloc, /* tp_alloc */
1034 set_new, /* tp_new */
1035 PyObject_GC_Del, /* tp_free */
1036};
1037
1038/* frozenset object ********************************************************/
1039
1040
1041static PyMethodDef frozenset_methods[] = {
1042 {"copy", (PyCFunction)set_copy, METH_NOARGS,
1043 copy_doc},
1044 {"__copy__", (PyCFunction)set_copy, METH_NOARGS,
1045 copy_doc},
1046 {"difference",(PyCFunction)set_difference, METH_O,
1047 difference_doc},
1048 {"intersection",(PyCFunction)set_intersection, METH_O,
1049 intersection_doc},
1050 {"issubset",(PyCFunction)set_issubset, METH_O,
1051 issubset_doc},
1052 {"issuperset",(PyCFunction)set_issuperset, METH_O,
1053 issuperset_doc},
1054 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
1055 reduce_doc},
1056 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
1057 symmetric_difference_doc},
1058 {"union", (PyCFunction)set_union, METH_O,
1059 union_doc},
1060 {NULL, NULL} /* sentinel */
1061};
1062
1063static PyNumberMethods frozenset_as_number = {
1064 0, /*nb_add*/
1065 (binaryfunc)set_sub, /*nb_subtract*/
1066 0, /*nb_multiply*/
1067 0, /*nb_divide*/
1068 0, /*nb_remainder*/
1069 0, /*nb_divmod*/
1070 0, /*nb_power*/
1071 0, /*nb_negative*/
1072 0, /*nb_positive*/
1073 0, /*nb_absolute*/
1074 0, /*nb_nonzero*/
1075 0, /*nb_invert*/
1076 0, /*nb_lshift*/
1077 0, /*nb_rshift*/
1078 (binaryfunc)set_and, /*nb_and*/
1079 (binaryfunc)set_xor, /*nb_xor*/
1080 (binaryfunc)set_or, /*nb_or*/
1081};
1082
1083PyDoc_STRVAR(frozenset_doc,
1084"frozenset(iterable) --> frozenset object\n\
1085\n\
1086Build an immutable unordered collection.");
1087
1088PyTypeObject PyFrozenSet_Type = {
1089 PyObject_HEAD_INIT(&PyType_Type)
1090 0, /* ob_size */
1091 "frozenset", /* tp_name */
1092 sizeof(PySetObject), /* tp_basicsize */
1093 0, /* tp_itemsize */
1094 /* methods */
1095 (destructor)set_dealloc, /* tp_dealloc */
1096 (printfunc)set_tp_print, /* tp_print */
1097 0, /* tp_getattr */
1098 0, /* tp_setattr */
1099 (cmpfunc)set_nocmp, /* tp_compare */
1100 (reprfunc)set_repr, /* tp_repr */
1101 &frozenset_as_number, /* tp_as_number */
1102 &set_as_sequence, /* tp_as_sequence */
1103 0, /* tp_as_mapping */
1104 frozenset_hash, /* tp_hash */
1105 0, /* tp_call */
1106 0, /* tp_str */
1107 PyObject_GenericGetAttr, /* tp_getattro */
1108 0, /* tp_setattro */
1109 0, /* tp_as_buffer */
1110 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
1111 Py_TPFLAGS_BASETYPE, /* tp_flags */
1112 frozenset_doc, /* tp_doc */
1113 (traverseproc)set_traverse, /* tp_traverse */
1114 0, /* tp_clear */
1115 (richcmpfunc)set_richcompare, /* tp_richcompare */
1116 0, /* tp_weaklistoffset */
1117 (getiterfunc)set_iter, /* tp_iter */
1118 0, /* tp_iternext */
1119 frozenset_methods, /* tp_methods */
1120 0, /* tp_members */
1121 0, /* tp_getset */
1122 0, /* tp_base */
1123 0, /* tp_dict */
1124 0, /* tp_descr_get */
1125 0, /* tp_descr_set */
1126 0, /* tp_dictoffset */
1127 0, /* tp_init */
1128 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001129 frozenset_new, /* tp_new */
Raymond Hettingera690a992003-11-16 16:17:49 +00001130 PyObject_GC_Del, /* tp_free */
1131};