blob: ce3f84eb69376011b685e5048e8d307334eb8219 [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 *
Raymond Hettingera38123e2003-11-24 22:18:49 +000013set_update(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +000014{
Raymond Hettingera38123e2003-11-24 22:18:49 +000015 PyObject *item, *data, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +000016
Raymond Hettingera38123e2003-11-24 22:18:49 +000017 if (PyAnySet_Check(other)) {
18 if (PyDict_Merge(so->data, ((PySetObject *)other)->data, 0) == -1)
19 return NULL;
20 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +000021 }
22
Raymond Hettingera38123e2003-11-24 22:18:49 +000023 it = PyObject_GetIter(other);
24 if (it == NULL)
25 return NULL;
26 data = so->data;
Raymond Hettingera690a992003-11-16 16:17:49 +000027
Raymond Hettingera38123e2003-11-24 22:18:49 +000028 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettingera690a992003-11-16 16:17:49 +000029 if (PyDict_SetItem(data, item, Py_True) == -1) {
Raymond Hettingera38123e2003-11-24 22:18:49 +000030 Py_DECREF(it);
Raymond Hettingera690a992003-11-16 16:17:49 +000031 Py_DECREF(item);
Raymond Hettingera38123e2003-11-24 22:18:49 +000032 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +000033 }
34 Py_DECREF(item);
35 }
Raymond Hettingera38123e2003-11-24 22:18:49 +000036 Py_DECREF(it);
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000037 if (PyErr_Occurred())
Raymond Hettingera38123e2003-11-24 22:18:49 +000038 return NULL;
39 Py_RETURN_NONE;
40}
41
42PyDoc_STRVAR(update_doc,
43"Update a set with the union of itself and another.");
44
45static PyObject *
46make_new_set(PyTypeObject *type, PyObject *iterable)
47{
48 PyObject *data = NULL;
49 PyObject *tmp;
50 PySetObject *so = NULL;
51
52 data = PyDict_New();
53 if (data == NULL)
54 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +000055
56 /* create PySetObject structure */
57 so = (PySetObject *)type->tp_alloc(type, 0);
Raymond Hettingera38123e2003-11-24 22:18:49 +000058 if (so == NULL) {
59 Py_DECREF(data);
60 return NULL;
61 }
Raymond Hettingera690a992003-11-16 16:17:49 +000062 so->data = data;
63 so->hash = -1;
64
Raymond Hettingera38123e2003-11-24 22:18:49 +000065 if (iterable != NULL) {
66 tmp = set_update(so, iterable);
67 if (tmp == NULL) {
68 Py_DECREF(so);
69 return NULL;
70 }
71 Py_DECREF(tmp);
72 }
73
Raymond Hettingera690a992003-11-16 16:17:49 +000074 return (PyObject *)so;
75}
76
77static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +000078frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +000079{
80 PyObject *iterable = NULL;
81
82 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
83 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +000084 if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
Raymond Hettinger49ba4c32003-11-23 02:49:05 +000085 Py_INCREF(iterable);
86 return iterable;
87 }
Raymond Hettingera690a992003-11-16 16:17:49 +000088 return make_new_set(type, iterable);
89}
90
Raymond Hettinger50a4bb32003-11-17 16:42:33 +000091static PyObject *
92set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
93{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +000094 return make_new_set(type, NULL);
95}
96
Raymond Hettingerbfd334a2003-11-22 03:55:23 +000097static PyObject *
98frozenset_dict_wrapper(PyObject *d)
99{
100 PySetObject *w;
101
102 assert(PyDict_Check(d));
103 w = (PySetObject *)make_new_set(&PyFrozenSet_Type, NULL);
104 if (w == NULL)
105 return NULL;
106 Py_DECREF(w->data);
107 Py_INCREF(d);
108 w->data = d;
109 return (PyObject *)w;
110}
111
Raymond Hettingera690a992003-11-16 16:17:49 +0000112static void
113set_dealloc(PySetObject *so)
114{
115 PyObject_GC_UnTrack(so);
116 Py_XDECREF(so->data);
117 so->ob_type->tp_free(so);
118}
119
120static int
121set_traverse(PySetObject *so, visitproc visit, void *arg)
122{
123 if (so->data)
124 return visit(so->data, arg);
125 return 0;
126}
127
128static PyObject *
129set_iter(PySetObject *so)
130{
131 return PyObject_GetIter(so->data);
132}
133
134static int
135set_len(PySetObject *so)
136{
137 return PyDict_Size(so->data);
138}
139
140static int
141set_contains(PySetObject *so, PyObject *key)
142{
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000143 PyObject *tmp;
Raymond Hettinger19c2d772003-11-21 18:36:54 +0000144 int result;
145
146 result = PySequence_Contains(so->data, key);
Raymond Hettingera38123e2003-11-24 22:18:49 +0000147 if (result == -1 && PyAnySet_Check(key)) {
Raymond Hettinger19c2d772003-11-21 18:36:54 +0000148 PyErr_Clear();
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000149 tmp = frozenset_dict_wrapper(((PySetObject *)(key))->data);
Raymond Hettinger19c2d772003-11-21 18:36:54 +0000150 if (tmp == NULL)
151 return -1;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000152 result = PySequence_Contains(so->data, tmp);
Raymond Hettinger19c2d772003-11-21 18:36:54 +0000153 Py_DECREF(tmp);
154 }
155 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +0000156}
157
158static PyObject *
159set_copy(PySetObject *so)
160{
Raymond Hettingera38123e2003-11-24 22:18:49 +0000161 return make_new_set(so->ob_type, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +0000162}
163
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000164static PyObject *
165frozenset_copy(PySetObject *so)
166{
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000167 if (PyFrozenSet_CheckExact(so)) {
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000168 Py_INCREF(so);
169 return (PyObject *)so;
170 }
171 return set_copy(so);
172}
173
Raymond Hettingera690a992003-11-16 16:17:49 +0000174PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
175
176static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000177set_union(PySetObject *so, PyObject *other)
178{
179 PySetObject *result;
180 PyObject *rv;
181
182 result = (PySetObject *)set_copy(so);
183 if (result == NULL)
184 return NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000185 rv = set_update(result, other);
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000186 if (rv == NULL) {
187 Py_DECREF(result);
188 return NULL;
189 }
190 Py_DECREF(rv);
191 return (PyObject *)result;
192}
193
194PyDoc_STRVAR(union_doc,
195 "Return the union of two sets as a new set.\n\
196\n\
197(i.e. all elements that are in either set.)");
198
199static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +0000200set_or(PySetObject *so, PyObject *other)
201{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000202 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000203 Py_INCREF(Py_NotImplemented);
204 return Py_NotImplemented;
205 }
206 return set_union(so, other);
207}
208
209static PyObject *
210set_ior(PySetObject *so, PyObject *other)
211{
212 PyObject *result;
213
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000214 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000215 Py_INCREF(Py_NotImplemented);
216 return Py_NotImplemented;
217 }
Raymond Hettingera38123e2003-11-24 22:18:49 +0000218 result = set_update(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000219 if (result == NULL)
220 return NULL;
221 Py_DECREF(result);
222 Py_INCREF(so);
223 return (PyObject *)so;
224}
225
226static PyObject *
227set_intersection(PySetObject *so, PyObject *other)
228{
229 PySetObject *result;
230 PyObject *item, *selfdata, *tgtdata, *it;
231
232 result = (PySetObject *)make_new_set(so->ob_type, NULL);
233 if (result == NULL)
234 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000235 tgtdata = result->data;
236 selfdata = so->data;
237
238 if (PyAnySet_Check(other) &&
239 PyDict_Size(((PySetObject *)other)->data) > PyDict_Size(selfdata)) {
240 selfdata = ((PySetObject *)other)->data;
241 other = (PyObject *)so;
242 } else if (PyDict_Check(other) &&
243 PyDict_Size(other) > PyDict_Size(selfdata)) {
244 selfdata = other;
245 other = so->data;
246 }
247
Raymond Hettingera690a992003-11-16 16:17:49 +0000248 it = PyObject_GetIter(other);
249 if (it == NULL) {
250 Py_DECREF(result);
251 return NULL;
252 }
253
Raymond Hettingera690a992003-11-16 16:17:49 +0000254 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000255 if (PySequence_Contains(selfdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000256 if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
257 Py_DECREF(it);
258 Py_DECREF(result);
259 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000260 return NULL;
261 }
262 }
263 Py_DECREF(item);
264 }
265 Py_DECREF(it);
266 if (PyErr_Occurred()) {
267 Py_DECREF(result);
268 return NULL;
269 }
270 return (PyObject *)result;
271}
272
273PyDoc_STRVAR(intersection_doc,
274"Return the intersection of two sets as a new set.\n\
275\n\
276(i.e. all elements that are in both sets.)");
277
278static PyObject *
279set_intersection_update(PySetObject *so, PyObject *other)
280{
281 PyObject *item, *selfdata, *it, *newdict, *tmp;
282
283 newdict = PyDict_New();
284 if (newdict == NULL)
285 return newdict;
286
287 it = PyObject_GetIter(other);
288 if (it == NULL) {
289 Py_DECREF(newdict);
290 return NULL;
291 }
292
293 selfdata = so->data;
294 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000295 if (PySequence_Contains(selfdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000296 if (PyDict_SetItem(newdict, item, Py_True) == -1) {
297 Py_DECREF(newdict);
298 Py_DECREF(it);
299 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000300 return NULL;
301 }
302 }
303 Py_DECREF(item);
304 }
305 Py_DECREF(it);
306 if (PyErr_Occurred()) {
307 Py_DECREF(newdict);
308 return NULL;
309 }
310 tmp = so->data;
311 so->data = newdict;
312 Py_DECREF(tmp);
313 Py_RETURN_NONE;
314}
315
316PyDoc_STRVAR(intersection_update_doc,
317"Update a set with the intersection of itself and another.");
318
319static PyObject *
320set_and(PySetObject *so, PyObject *other)
321{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000322 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000323 Py_INCREF(Py_NotImplemented);
324 return Py_NotImplemented;
325 }
326 return set_intersection(so, other);
327}
328
329static PyObject *
330set_iand(PySetObject *so, PyObject *other)
331{
332 PyObject *result;
333
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000334 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000335 Py_INCREF(Py_NotImplemented);
336 return Py_NotImplemented;
337 }
338 result = set_intersection_update(so, other);
339 if (result == NULL)
340 return NULL;
341 Py_DECREF(result);
342 Py_INCREF(so);
343 return (PyObject *)so;
344}
345
346static PyObject *
347set_difference(PySetObject *so, PyObject *other)
348{
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000349 PySetObject *result, *otherset=NULL;
350 PyObject *item, *otherdata, *tgtdata, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000351
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000352 result = (PySetObject *)make_new_set(so->ob_type, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +0000353 if (result == NULL)
354 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000355 tgtdata = result->data;
356
357 if (PyDict_Check(other))
358 otherdata = other;
359 else if (PyAnySet_Check(other))
360 otherdata = ((PySetObject *)other)->data;
361 else {
362 otherset = (PySetObject *)make_new_set(so->ob_type, other);
363 if (otherset == NULL) {
364 Py_DECREF(result);
365 return NULL;
366 }
367 otherdata = otherset->data;
368 }
369
370 it = PyObject_GetIter(so->data);
Raymond Hettingera690a992003-11-16 16:17:49 +0000371 if (it == NULL) {
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000372 Py_XDECREF(otherset);
Raymond Hettingera690a992003-11-16 16:17:49 +0000373 Py_DECREF(result);
374 return NULL;
375 }
376
Raymond Hettingera690a992003-11-16 16:17:49 +0000377 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000378 if (!PySequence_Contains(otherdata, item)) {
379 if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
380 Py_XDECREF(otherset);
Raymond Hettingera690a992003-11-16 16:17:49 +0000381 Py_DECREF(it);
Raymond Hettingera690a992003-11-16 16:17:49 +0000382 Py_DECREF(item);
383 return NULL;
384 }
385 }
386 Py_DECREF(item);
387 }
388 Py_DECREF(it);
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000389 Py_XDECREF(otherset);
Raymond Hettingera690a992003-11-16 16:17:49 +0000390 if (PyErr_Occurred()) {
391 Py_DECREF(result);
392 return NULL;
393 }
394 return (PyObject *)result;
395}
396
397PyDoc_STRVAR(difference_doc,
398"Return the difference of two sets as a new set.\n\
399\n\
400(i.e. all elements that are in this set but not the other.)");
401
402static PyObject *
403set_difference_update(PySetObject *so, PyObject *other)
404{
405 PyObject *item, *tgtdata, *it;
406
407 it = PyObject_GetIter(other);
408 if (it == NULL)
409 return NULL;
410
411 tgtdata = so->data;
412 while ((item = PyIter_Next(it)) != NULL) {
413 if (PyDict_DelItem(tgtdata, item) == -1) {
414 if (PyErr_ExceptionMatches(PyExc_KeyError))
415 PyErr_Clear();
416 else {
417 Py_DECREF(it);
418 Py_DECREF(item);
419 return NULL;
420 }
421 }
422 Py_DECREF(item);
423 }
424 Py_DECREF(it);
425 if (PyErr_Occurred())
426 return NULL;
427 Py_RETURN_NONE;
428}
429
430PyDoc_STRVAR(difference_update_doc,
431"Remove all elements of another set from this set.");
432
433static PyObject *
434set_sub(PySetObject *so, PyObject *other)
435{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000436 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000437 Py_INCREF(Py_NotImplemented);
438 return Py_NotImplemented;
439 }
440 return set_difference(so, other);
441}
442
443static PyObject *
444set_isub(PySetObject *so, PyObject *other)
445{
446 PyObject *result;
447
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000448 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000449 Py_INCREF(Py_NotImplemented);
450 return Py_NotImplemented;
451 }
452 result = set_difference_update(so, other);
453 if (result == NULL)
454 return NULL;
455 Py_DECREF(result);
456 Py_INCREF(so);
457 return (PyObject *)so;
458}
459
460static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +0000461set_symmetric_difference_update(PySetObject *so, PyObject *other)
462{
463 PyObject *item, *selfdata, *it, *otherdata;
464 PySetObject *otherset = NULL;
465
466 selfdata = so->data;
467
468 if (PyDict_Check(other))
469 otherdata = other;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000470 else if (PyAnySet_Check(other))
Raymond Hettingera690a992003-11-16 16:17:49 +0000471 otherdata = ((PySetObject *)other)->data;
472 else {
473 otherset = (PySetObject *)make_new_set(so->ob_type, other);
474 if (otherset == NULL)
475 return NULL;
476 otherdata = otherset->data;
477 }
478
479 it = PyObject_GetIter(otherdata);
480 if (it == NULL)
481 return NULL;
482
483 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000484 if (PySequence_Contains(selfdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000485 if (PyDict_DelItem(selfdata, item) == -1) {
486 Py_XDECREF(otherset);
487 Py_DECREF(it);
488 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000489 return NULL;
490 }
491 } else {
492 if (PyDict_SetItem(selfdata, item, Py_True) == -1) {
493 Py_XDECREF(otherset);
494 Py_DECREF(it);
495 Py_DECREF(item);
Raymond Hettingera690a992003-11-16 16:17:49 +0000496 return NULL;
497 }
498 }
499 Py_DECREF(item);
500 }
501 Py_XDECREF(otherset);
502 Py_DECREF(it);
503 if (PyErr_Occurred())
504 return NULL;
505 Py_RETURN_NONE;
506}
507
508PyDoc_STRVAR(symmetric_difference_update_doc,
509"Update a set with the symmetric difference of itself and another.");
510
511static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +0000512set_symmetric_difference(PySetObject *so, PyObject *other)
513{
514 PySetObject *result;
515 PyObject *item, *selfdata, *otherdata, *tgtdata, *it, *rv, *otherset;
516
517 if (PyDict_Check(other))
518 otherdata = other;
519 else if (PyAnySet_Check(other))
520 otherdata = ((PySetObject *)other)->data;
521 else {
522 otherset = make_new_set(so->ob_type, other);
523 if (otherset == NULL)
524 return NULL;
525 rv = set_symmetric_difference_update((PySetObject *)otherset, (PyObject *)so);
526 if (rv == NULL)
527 return NULL;
528 Py_DECREF(rv);
529 return otherset;
530 }
531
532 result = (PySetObject *)make_new_set(so->ob_type, NULL);
533 if (result == NULL)
534 return NULL;
535 tgtdata = result->data;
536 selfdata = so->data;
537
538 it = PyObject_GetIter(otherdata);
539 if (it == NULL) {
540 Py_DECREF(result);
541 return NULL;
542 }
543 while ((item = PyIter_Next(it)) != NULL) {
544 if (!PySequence_Contains(selfdata, item)) {
545 if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
546 Py_DECREF(it);
547 Py_DECREF(item);
548 return NULL;
549 }
550 }
551 Py_DECREF(item);
552 }
553 Py_DECREF(it);
554 if (PyErr_Occurred()) {
555 Py_DECREF(result);
556 return NULL;
557 }
558
559 it = PyObject_GetIter(selfdata);
560 if (it == NULL) {
561 Py_DECREF(result);
562 return NULL;
563 }
564 while ((item = PyIter_Next(it)) != NULL) {
565 if (!PySequence_Contains(otherdata, item)) {
566 if (PyDict_SetItem(tgtdata, item, Py_True) == -1) {
567 Py_DECREF(it);
568 Py_DECREF(item);
569 return NULL;
570 }
571 }
572 Py_DECREF(item);
573 }
574 Py_DECREF(it);
575 if (PyErr_Occurred()) {
576 Py_DECREF(result);
577 return NULL;
578 }
579
580 return (PyObject *)result;
581}
582
583PyDoc_STRVAR(symmetric_difference_doc,
584"Return the symmetric difference of two sets as a new set.\n\
585\n\
586(i.e. all elements that are in exactly one of the sets.)");
587
588static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +0000589set_xor(PySetObject *so, PyObject *other)
590{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000591 if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000592 Py_INCREF(Py_NotImplemented);
593 return Py_NotImplemented;
594 }
595 return set_symmetric_difference(so, other);
596}
597
598static PyObject *
599set_ixor(PySetObject *so, PyObject *other)
600{
601 PyObject *result;
602
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000603 if (!PyAnySet_Check(other)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000604 Py_INCREF(Py_NotImplemented);
605 return Py_NotImplemented;
606 }
607 result = set_symmetric_difference_update(so, other);
608 if (result == NULL)
609 return NULL;
610 Py_DECREF(result);
611 Py_INCREF(so);
612 return (PyObject *)so;
613}
614
615static PyObject *
616set_issubset(PySetObject *so, PyObject *other)
617{
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000618 PyObject *otherdata, *it, *item, *tmp, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +0000619
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000620 if (!PyAnySet_Check(other)) {
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000621 tmp = make_new_set(&PySet_Type, other);
622 if (tmp == NULL)
623 return NULL;
624 result = set_issubset(so, tmp);
625 Py_DECREF(tmp);
626 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +0000627 }
628 if (set_len(so) > set_len((PySetObject *)other))
629 Py_RETURN_FALSE;
630
631 it = PyObject_GetIter(so->data);
632 if (it == NULL)
633 return NULL;
634
635 otherdata = ((PySetObject *)other)->data;
636 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger1b92fd52003-11-18 14:15:31 +0000637 if (!PySequence_Contains(otherdata, item)) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000638 Py_DECREF(it);
639 Py_DECREF(item);
640 Py_RETURN_FALSE;
641 }
642 Py_DECREF(item);
643 }
644 Py_DECREF(it);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000645 if (PyErr_Occurred())
646 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000647 Py_RETURN_TRUE;
648}
649
650PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
651
652static PyObject *
653set_issuperset(PySetObject *so, PyObject *other)
654{
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000655 PyObject *tmp, *result;
656
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000657 if (!PyAnySet_Check(other)) {
Raymond Hettinger3fbec702003-11-21 07:56:36 +0000658 tmp = make_new_set(&PySet_Type, other);
659 if (tmp == NULL)
660 return NULL;
661 result = set_issuperset(so, tmp);
662 Py_DECREF(tmp);
663 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +0000664 }
665 return set_issubset((PySetObject *)other, (PyObject *)so);
666}
667
668PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
669
670static long
671set_nohash(PyObject *self)
672{
673 PyErr_SetString(PyExc_TypeError, "set objects are unhashable");
674 return -1;
675}
676
677static int
678set_nocmp(PyObject *self)
679{
680 PyErr_SetString(PyExc_TypeError, "cannot compare sets using cmp()");
681 return -1;
682}
683
684static long
685frozenset_hash(PyObject *self)
686{
687 PyObject *it, *item;
688 PySetObject *so = (PySetObject *)self;
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000689 long hash = 0;
Raymond Hettingera690a992003-11-16 16:17:49 +0000690
691 if (so->hash != -1)
692 return so->hash;
693
694 it = PyObject_GetIter(((PySetObject *)so)->data);
695 if (it == NULL)
696 return -1;
697
698 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettinger49ba4c32003-11-23 02:49:05 +0000699 /* Multiplying by a large prime increases the bit dispersion for
700 closely spaced hash values. The is important because some
701 use cases have many combinations of a small number of
702 elements with nearby hashes so that many distinct combinations
703 collapse to only a handful of distinct hash values. */
Guido van Rossum5f4e45d2003-11-24 04:13:13 +0000704 hash ^= PyObject_Hash(item) * 3644798167u;
Raymond Hettingera690a992003-11-16 16:17:49 +0000705 Py_DECREF(item);
706 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000707 Py_DECREF(it);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000708 if (PyErr_Occurred())
709 return -1;
710 so->hash = hash;
Raymond Hettingera690a992003-11-16 16:17:49 +0000711 return hash;
712}
713
714static PyObject *
715set_richcompare(PySetObject *v, PyObject *w, int op)
716{
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000717 if(!PyAnySet_Check(w)) {
718 if (op == Py_EQ)
719 Py_RETURN_FALSE;
720 if (op == Py_NE)
721 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +0000722 PyErr_SetString(PyExc_TypeError, "can only compare to a set");
723 return NULL;
724 }
725 switch (op) {
726 case Py_EQ:
727 case Py_NE:
728 return PyObject_RichCompare(((PySetObject *)v)->data,
729 ((PySetObject *)w)->data, op);
730 case Py_LE:
731 return set_issubset((PySetObject *)v, w);
732 case Py_GE:
733 return set_issuperset((PySetObject *)v, w);
734 case Py_LT:
735 if (set_len(v) >= set_len((PySetObject *)w))
736 Py_RETURN_FALSE;
737 return set_issubset((PySetObject *)v, w);
738 case Py_GT:
739 if (set_len(v) <= set_len((PySetObject *)w))
740 Py_RETURN_FALSE;
741 return set_issuperset((PySetObject *)v, w);
742 }
743 Py_INCREF(Py_NotImplemented);
744 return Py_NotImplemented;
745}
746
747static PyObject *
748set_repr(PySetObject *so)
749{
750 PyObject *keys, *result, *listrepr;
751
752 keys = PyDict_Keys(so->data);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000753 if (keys == NULL)
754 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000755 listrepr = PyObject_Repr(keys);
756 Py_DECREF(keys);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000757 if (listrepr == NULL)
758 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +0000759
760 result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
761 PyString_AS_STRING(listrepr));
762 Py_DECREF(listrepr);
763 return result;
764}
765
766static int
767set_tp_print(PySetObject *so, FILE *fp, int flags)
768{
769 PyObject *it, *item;
770 int firstpass=1;
771
772 it = PyObject_GetIter(so->data);
773 if (it == NULL)
774 return -1;
775 fprintf(fp, "%s([", so->ob_type->tp_name);
776
777 while ((item = PyIter_Next(it)) != NULL) {
778 if (firstpass == 1)
779 firstpass = 0;
780 else
Raymond Hettingere2c277a2003-11-16 16:36:58 +0000781 fprintf(fp, ", ");
Raymond Hettingera690a992003-11-16 16:17:49 +0000782 if (PyObject_Print(item, fp, 0) != 0) {
783 Py_DECREF(it);
784 Py_DECREF(item);
785 return -1;
786 }
787 Py_DECREF(item);
788 }
789 Py_DECREF(it);
790 fprintf(fp, "])");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000791 if (PyErr_Occurred())
792 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000793 return 0;
794}
795
796static PyObject *
797set_clear(PySetObject *so)
798{
799 PyDict_Clear(so->data);
800 so->hash = -1;
801 Py_INCREF(Py_None);
802 return Py_None;
803}
804
805PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
806
807static int
808set_tp_clear(PySetObject *so)
809{
810 PyDict_Clear(so->data);
811 so->hash = -1;
812 return 0;
813}
814
815static PyObject *
816set_add(PySetObject *so, PyObject *item)
817{
818 if (PyDict_SetItem(so->data, item, Py_True) == -1)
819 return NULL;
820 Py_INCREF(Py_None);
821 return Py_None;
822}
823
824PyDoc_STRVAR(add_doc,
825"Add an element to a set.\n\
826\n\
827This has no effect if the element is already present.");
828
829static PyObject *
830set_remove(PySetObject *so, PyObject *item)
831{
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000832 PyObject *tmp;
833
834 if (PyDict_DelItem(so->data, item) == -1) {
835 if (!PyType_IsSubtype(item->ob_type, &PySet_Type))
836 return NULL;
837 PyErr_Clear();
838 tmp = frozenset_dict_wrapper(((PySetObject *)(item))->data);
839 if (tmp == NULL)
840 return NULL;
841 if (PyDict_DelItem(so->data, tmp) == -1) {
842 Py_DECREF(tmp);
843 return NULL;
844 }
845 Py_DECREF(tmp);
846 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000847 Py_INCREF(Py_None);
848 return Py_None;
849}
850
851PyDoc_STRVAR(remove_doc,
852"Remove an element from a set; it must be a member.\n\
853\n\
854If the element is not a member, raise a KeyError.");
855
856static PyObject *
857set_discard(PySetObject *so, PyObject *item)
858{
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000859 PyObject *tmp;
860
Guido van Rossumb61982b2003-11-18 19:27:19 +0000861 if (PyDict_DelItem(so->data, item) == -1) {
Raymond Hettingera690a992003-11-16 16:17:49 +0000862 if (PyErr_ExceptionMatches(PyExc_KeyError))
863 PyErr_Clear();
Raymond Hettingerbfd334a2003-11-22 03:55:23 +0000864 else {
865 if (!PyType_IsSubtype(item->ob_type, &PySet_Type))
866 return NULL;
867 PyErr_Clear();
868 tmp = frozenset_dict_wrapper(((PySetObject *)(item))->data);
869 if (tmp == NULL)
870 return NULL;
871 if (PyDict_DelItem(so->data, tmp) == -1) {
872 if (PyErr_ExceptionMatches(PyExc_KeyError))
873 PyErr_Clear();
874 else {
875 Py_DECREF(tmp);
876 return NULL;
877 }
878 }
879 Py_DECREF(tmp);
880 }
Guido van Rossumb61982b2003-11-18 19:27:19 +0000881 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000882 Py_INCREF(Py_None);
883 return Py_None;
884}
885
886PyDoc_STRVAR(discard_doc,
887"Remove an element from a set if it is a member.\n\
888\n\
889If the element is not a member, do nothing.");
890
891static PyObject *
892set_pop(PySetObject *so)
893{
894 PyObject *key, *value;
895 int pos = 0;
896
897 if (!PyDict_Next(so->data, &pos, &key, &value)) {
898 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
899 return NULL;
900 }
901 Py_INCREF(key);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000902 if (PyDict_DelItem(so->data, key) == -1) {
903 Py_DECREF(key);
904 return NULL;
905 }
Raymond Hettingera690a992003-11-16 16:17:49 +0000906 return key;
907}
908
909PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.");
910
911static PyObject *
912set_reduce(PySetObject *so)
913{
914 PyObject *keys=NULL, *args=NULL, *result=NULL;
915
916 keys = PyDict_Keys(so->data);
917 if (keys == NULL)
918 goto done;
919 args = PyTuple_Pack(1, keys);
920 if (args == NULL)
921 goto done;
922 result = PyTuple_Pack(2, so->ob_type, args);
923done:
924 Py_XDECREF(args);
925 Py_XDECREF(keys);
926 return result;
927}
928
929PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
930
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000931static int
932set_init(PySetObject *self, PyObject *args, PyObject *kwds)
933{
934 PyObject *iterable = NULL;
935 PyObject *result;
936
937 if (!PyAnySet_Check(self))
938 return -1;
939 if (!PyArg_UnpackTuple(args, self->ob_type->tp_name, 0, 1, &iterable))
940 return -1;
941 PyDict_Clear(self->data);
942 self->hash = -1;
943 if (iterable == NULL)
944 return 0;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000945 result = set_update(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +0000946 if (result != NULL) {
947 Py_DECREF(result);
948 return 0;
949 }
950 return -1;
951}
952
Raymond Hettingera690a992003-11-16 16:17:49 +0000953static PySequenceMethods set_as_sequence = {
954 (inquiry)set_len, /* sq_length */
955 0, /* sq_concat */
956 0, /* sq_repeat */
957 0, /* sq_item */
958 0, /* sq_slice */
959 0, /* sq_ass_item */
960 0, /* sq_ass_slice */
961 (objobjproc)set_contains, /* sq_contains */
962};
963
964/* set object ********************************************************/
965
966static PyMethodDef set_methods[] = {
967 {"add", (PyCFunction)set_add, METH_O,
968 add_doc},
969 {"clear", (PyCFunction)set_clear, METH_NOARGS,
970 clear_doc},
971 {"copy", (PyCFunction)set_copy, METH_NOARGS,
972 copy_doc},
973 {"__copy__", (PyCFunction)set_copy, METH_NOARGS,
974 copy_doc},
975 {"discard", (PyCFunction)set_discard, METH_O,
976 discard_doc},
977 {"difference", (PyCFunction)set_difference, METH_O,
978 difference_doc},
979 {"difference_update", (PyCFunction)set_difference_update, METH_O,
980 difference_update_doc},
981 {"intersection",(PyCFunction)set_intersection, METH_O,
982 intersection_doc},
983 {"intersection_update",(PyCFunction)set_intersection_update, METH_O,
984 intersection_update_doc},
985 {"issubset", (PyCFunction)set_issubset, METH_O,
986 issubset_doc},
987 {"issuperset", (PyCFunction)set_issuperset, METH_O,
988 issuperset_doc},
989 {"pop", (PyCFunction)set_pop, METH_NOARGS,
990 pop_doc},
991 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
992 reduce_doc},
993 {"remove", (PyCFunction)set_remove, METH_O,
994 remove_doc},
995 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
996 symmetric_difference_doc},
997 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
998 symmetric_difference_update_doc},
999 {"union", (PyCFunction)set_union, METH_O,
1000 union_doc},
Raymond Hettingera38123e2003-11-24 22:18:49 +00001001 {"update", (PyCFunction)set_update, METH_O,
1002 update_doc},
Raymond Hettingera690a992003-11-16 16:17:49 +00001003 {NULL, NULL} /* sentinel */
1004};
1005
1006static PyNumberMethods set_as_number = {
1007 0, /*nb_add*/
1008 (binaryfunc)set_sub, /*nb_subtract*/
1009 0, /*nb_multiply*/
1010 0, /*nb_divide*/
1011 0, /*nb_remainder*/
1012 0, /*nb_divmod*/
1013 0, /*nb_power*/
1014 0, /*nb_negative*/
1015 0, /*nb_positive*/
1016 0, /*nb_absolute*/
1017 0, /*nb_nonzero*/
1018 0, /*nb_invert*/
1019 0, /*nb_lshift*/
1020 0, /*nb_rshift*/
1021 (binaryfunc)set_and, /*nb_and*/
1022 (binaryfunc)set_xor, /*nb_xor*/
1023 (binaryfunc)set_or, /*nb_or*/
1024 0, /*nb_coerce*/
1025 0, /*nb_int*/
1026 0, /*nb_long*/
1027 0, /*nb_float*/
1028 0, /*nb_oct*/
1029 0, /*nb_hex*/
1030 0, /*nb_inplace_add*/
1031 (binaryfunc)set_isub, /*nb_inplace_subtract*/
1032 0, /*nb_inplace_multiply*/
1033 0, /*nb_inplace_divide*/
1034 0, /*nb_inplace_remainder*/
1035 0, /*nb_inplace_power*/
1036 0, /*nb_inplace_lshift*/
1037 0, /*nb_inplace_rshift*/
1038 (binaryfunc)set_iand, /*nb_inplace_and*/
1039 (binaryfunc)set_ixor, /*nb_inplace_xor*/
1040 (binaryfunc)set_ior, /*nb_inplace_or*/
1041};
1042
1043PyDoc_STRVAR(set_doc,
1044"set(iterable) --> set object\n\
1045\n\
1046Build an unordered collection.");
1047
1048PyTypeObject PySet_Type = {
1049 PyObject_HEAD_INIT(&PyType_Type)
1050 0, /* ob_size */
1051 "set", /* tp_name */
1052 sizeof(PySetObject), /* tp_basicsize */
1053 0, /* tp_itemsize */
1054 /* methods */
1055 (destructor)set_dealloc, /* tp_dealloc */
1056 (printfunc)set_tp_print, /* tp_print */
1057 0, /* tp_getattr */
1058 0, /* tp_setattr */
1059 (cmpfunc)set_nocmp, /* tp_compare */
1060 (reprfunc)set_repr, /* tp_repr */
1061 &set_as_number, /* tp_as_number */
1062 &set_as_sequence, /* tp_as_sequence */
1063 0, /* tp_as_mapping */
1064 set_nohash, /* tp_hash */
1065 0, /* tp_call */
1066 0, /* tp_str */
1067 PyObject_GenericGetAttr, /* tp_getattro */
1068 0, /* tp_setattro */
1069 0, /* tp_as_buffer */
1070 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
1071 Py_TPFLAGS_BASETYPE, /* tp_flags */
1072 set_doc, /* tp_doc */
1073 (traverseproc)set_traverse, /* tp_traverse */
1074 (inquiry)set_tp_clear, /* tp_clear */
1075 (richcmpfunc)set_richcompare, /* tp_richcompare */
1076 0, /* tp_weaklistoffset */
1077 (getiterfunc)set_iter, /* tp_iter */
1078 0, /* tp_iternext */
1079 set_methods, /* tp_methods */
1080 0, /* tp_members */
1081 0, /* tp_getset */
1082 0, /* tp_base */
1083 0, /* tp_dict */
1084 0, /* tp_descr_get */
1085 0, /* tp_descr_set */
1086 0, /* tp_dictoffset */
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001087 (initproc)set_init, /* tp_init */
Raymond Hettingera690a992003-11-16 16:17:49 +00001088 PyType_GenericAlloc, /* tp_alloc */
1089 set_new, /* tp_new */
1090 PyObject_GC_Del, /* tp_free */
1091};
1092
1093/* frozenset object ********************************************************/
1094
1095
1096static PyMethodDef frozenset_methods[] = {
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001097 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
Raymond Hettingera690a992003-11-16 16:17:49 +00001098 copy_doc},
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001099 {"__copy__", (PyCFunction)frozenset_copy, METH_NOARGS,
Raymond Hettingera690a992003-11-16 16:17:49 +00001100 copy_doc},
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001101 {"difference", (PyCFunction)set_difference, METH_O,
Raymond Hettingera690a992003-11-16 16:17:49 +00001102 difference_doc},
1103 {"intersection",(PyCFunction)set_intersection, METH_O,
1104 intersection_doc},
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001105 {"issubset", (PyCFunction)set_issubset, METH_O,
Raymond Hettingera690a992003-11-16 16:17:49 +00001106 issubset_doc},
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001107 {"issuperset", (PyCFunction)set_issuperset, METH_O,
Raymond Hettingera690a992003-11-16 16:17:49 +00001108 issuperset_doc},
1109 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
1110 reduce_doc},
1111 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
1112 symmetric_difference_doc},
1113 {"union", (PyCFunction)set_union, METH_O,
1114 union_doc},
1115 {NULL, NULL} /* sentinel */
1116};
1117
1118static PyNumberMethods frozenset_as_number = {
1119 0, /*nb_add*/
1120 (binaryfunc)set_sub, /*nb_subtract*/
1121 0, /*nb_multiply*/
1122 0, /*nb_divide*/
1123 0, /*nb_remainder*/
1124 0, /*nb_divmod*/
1125 0, /*nb_power*/
1126 0, /*nb_negative*/
1127 0, /*nb_positive*/
1128 0, /*nb_absolute*/
1129 0, /*nb_nonzero*/
1130 0, /*nb_invert*/
1131 0, /*nb_lshift*/
1132 0, /*nb_rshift*/
1133 (binaryfunc)set_and, /*nb_and*/
1134 (binaryfunc)set_xor, /*nb_xor*/
1135 (binaryfunc)set_or, /*nb_or*/
1136};
1137
1138PyDoc_STRVAR(frozenset_doc,
1139"frozenset(iterable) --> frozenset object\n\
1140\n\
1141Build an immutable unordered collection.");
1142
1143PyTypeObject PyFrozenSet_Type = {
1144 PyObject_HEAD_INIT(&PyType_Type)
1145 0, /* ob_size */
1146 "frozenset", /* tp_name */
1147 sizeof(PySetObject), /* tp_basicsize */
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001148 0, /* tp_itemsize */ /* methods */
Raymond Hettingera690a992003-11-16 16:17:49 +00001149 (destructor)set_dealloc, /* tp_dealloc */
1150 (printfunc)set_tp_print, /* tp_print */
1151 0, /* tp_getattr */
1152 0, /* tp_setattr */
1153 (cmpfunc)set_nocmp, /* tp_compare */
1154 (reprfunc)set_repr, /* tp_repr */
1155 &frozenset_as_number, /* tp_as_number */
1156 &set_as_sequence, /* tp_as_sequence */
1157 0, /* tp_as_mapping */
1158 frozenset_hash, /* tp_hash */
1159 0, /* tp_call */
1160 0, /* tp_str */
1161 PyObject_GenericGetAttr, /* tp_getattro */
1162 0, /* tp_setattro */
1163 0, /* tp_as_buffer */
1164 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
1165 Py_TPFLAGS_BASETYPE, /* tp_flags */
1166 frozenset_doc, /* tp_doc */
1167 (traverseproc)set_traverse, /* tp_traverse */
1168 0, /* tp_clear */
1169 (richcmpfunc)set_richcompare, /* tp_richcompare */
1170 0, /* tp_weaklistoffset */
1171 (getiterfunc)set_iter, /* tp_iter */
1172 0, /* tp_iternext */
1173 frozenset_methods, /* tp_methods */
1174 0, /* tp_members */
1175 0, /* tp_getset */
1176 0, /* tp_base */
1177 0, /* tp_dict */
1178 0, /* tp_descr_get */
1179 0, /* tp_descr_set */
1180 0, /* tp_dictoffset */
1181 0, /* tp_init */
1182 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001183 frozenset_new, /* tp_new */
Raymond Hettingera690a992003-11-16 16:17:49 +00001184 PyObject_GC_Del, /* tp_free */
1185};