2 #include "structmember.h"
4 /* set object implementation
5 written and maintained by Raymond D. Hettinger <python@rcn.com>
6 derived from sets.py written by Greg V. Wilson, Alex Martelli,
7 Guido van Rossum, Raymond Hettinger, and Tim Peters.
9 Copyright (c) 2003 Python Software Foundation.
14 #pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)
18 set_update(PySetObject
*so
, PyObject
*other
)
20 PyObject
*item
, *data
, *it
;
22 if (PyAnySet_Check(other
)) {
23 if (PyDict_Merge(so
->data
, ((PySetObject
*)other
)->data
, 1) == -1)
28 it
= PyObject_GetIter(other
);
33 while ((item
= PyIter_Next(it
)) != NULL
) {
34 if (PyDict_SetItem(data
, item
, Py_True
) == -1) {
47 PyDoc_STRVAR(update_doc
,
48 "Update a set with the union of itself and another.");
51 make_new_set(PyTypeObject
*type
, PyObject
*iterable
)
53 PyObject
*data
= NULL
;
55 PySetObject
*so
= NULL
;
61 /* create PySetObject structure */
62 so
= (PySetObject
*)type
->tp_alloc(type
, 0);
69 so
->weakreflist
= NULL
;
71 if (iterable
!= NULL
) {
72 tmp
= set_update(so
, iterable
);
80 return (PyObject
*)so
;
84 frozenset_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
86 PyObject
*iterable
= NULL
;
88 if (!PyArg_UnpackTuple(args
, type
->tp_name
, 0, 1, &iterable
))
90 if (iterable
!= NULL
&& PyFrozenSet_CheckExact(iterable
)) {
94 return make_new_set(type
, iterable
);
98 set_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
100 return make_new_set(type
, NULL
);
104 frozenset_dict_wrapper(PyObject
*d
)
108 assert(PyDict_Check(d
));
109 w
= (PySetObject
*)make_new_set(&PyFrozenSet_Type
, NULL
);
115 return (PyObject
*)w
;
119 set_dealloc(PySetObject
*so
)
121 if (so
->weakreflist
!= NULL
)
122 PyObject_ClearWeakRefs((PyObject
*) so
);
123 Py_XDECREF(so
->data
);
124 so
->ob_type
->tp_free(so
);
128 set_iter(PySetObject
*so
)
130 return PyObject_GetIter(so
->data
);
134 set_len(PySetObject
*so
)
136 return PyDict_Size(so
->data
);
140 set_contains(PySetObject
*so
, PyObject
*key
)
145 result
= PyDict_Contains(so
->data
, key
);
146 if (result
== -1 && PyAnySet_Check(key
)) {
148 tmp
= frozenset_dict_wrapper(((PySetObject
*)(key
))->data
);
151 result
= PyDict_Contains(so
->data
, tmp
);
158 set_direct_contains(PySetObject
*so
, PyObject
*key
)
162 result
= set_contains(so
, key
);
165 return PyBool_FromLong(result
);
168 PyDoc_STRVAR(contains_doc
, "x.__contains__(y) <==> y in x.");
171 set_copy(PySetObject
*so
)
173 return make_new_set(so
->ob_type
, (PyObject
*)so
);
177 frozenset_copy(PySetObject
*so
)
179 if (PyFrozenSet_CheckExact(so
)) {
181 return (PyObject
*)so
;
186 PyDoc_STRVAR(copy_doc
, "Return a shallow copy of a set.");
189 set_union(PySetObject
*so
, PyObject
*other
)
194 result
= (PySetObject
*)set_copy(so
);
197 rv
= set_update(result
, other
);
203 return (PyObject
*)result
;
206 PyDoc_STRVAR(union_doc
,
207 "Return the union of two sets as a new set.\n\
209 (i.e. all elements that are in either set.)");
212 set_or(PySetObject
*so
, PyObject
*other
)
214 if (!PyAnySet_Check(so
) || !PyAnySet_Check(other
)) {
215 Py_INCREF(Py_NotImplemented
);
216 return Py_NotImplemented
;
218 return set_union(so
, other
);
222 set_ior(PySetObject
*so
, PyObject
*other
)
226 if (!PyAnySet_Check(other
)) {
227 Py_INCREF(Py_NotImplemented
);
228 return Py_NotImplemented
;
230 result
= set_update(so
, other
);
235 return (PyObject
*)so
;
239 set_intersection(PySetObject
*so
, PyObject
*other
)
242 PyObject
*item
, *selfdata
, *tgtdata
, *it
, *tmp
;
244 result
= (PySetObject
*)make_new_set(so
->ob_type
, NULL
);
247 tgtdata
= result
->data
;
250 if (PyAnySet_Check(other
))
251 other
= ((PySetObject
*)other
)->data
;
253 if (PyDict_Check(other
) && PyDict_Size(other
) > PyDict_Size(selfdata
)) {
259 if (PyDict_CheckExact(other
)) {
262 while (PyDict_Next(other
, &pos
, &item
, &value
)) {
263 if (PyDict_Contains(selfdata
, item
)) {
264 if (PyDict_SetItem(tgtdata
, item
, Py_True
) == -1) {
270 return (PyObject
*)result
;
273 it
= PyObject_GetIter(other
);
279 while ((item
= PyIter_Next(it
)) != NULL
) {
280 if (PyDict_Contains(selfdata
, item
)) {
281 if (PyDict_SetItem(tgtdata
, item
, Py_True
) == -1) {
291 if (PyErr_Occurred()) {
295 return (PyObject
*)result
;
298 PyDoc_STRVAR(intersection_doc
,
299 "Return the intersection of two sets as a new set.\n\
301 (i.e. all elements that are in both sets.)");
304 set_intersection_update(PySetObject
*so
, PyObject
*other
)
306 PyObject
*item
, *selfdata
, *it
, *newdict
, *tmp
;
308 newdict
= PyDict_New();
312 it
= PyObject_GetIter(other
);
319 while ((item
= PyIter_Next(it
)) != NULL
) {
320 if (PyDict_Contains(selfdata
, item
)) {
321 if (PyDict_SetItem(newdict
, item
, Py_True
) == -1) {
331 if (PyErr_Occurred()) {
341 PyDoc_STRVAR(intersection_update_doc
,
342 "Update a set with the intersection of itself and another.");
345 set_and(PySetObject
*so
, PyObject
*other
)
347 if (!PyAnySet_Check(so
) || !PyAnySet_Check(other
)) {
348 Py_INCREF(Py_NotImplemented
);
349 return Py_NotImplemented
;
351 return set_intersection(so
, other
);
355 set_iand(PySetObject
*so
, PyObject
*other
)
359 if (!PyAnySet_Check(other
)) {
360 Py_INCREF(Py_NotImplemented
);
361 return Py_NotImplemented
;
363 result
= set_intersection_update(so
, other
);
368 return (PyObject
*)so
;
372 set_difference_update(PySetObject
*so
, PyObject
*other
)
374 PyObject
*item
, *tgtdata
, *it
;
376 it
= PyObject_GetIter(other
);
381 while ((item
= PyIter_Next(it
)) != NULL
) {
382 if (PyDict_DelItem(tgtdata
, item
) == -1) {
383 if (PyErr_ExceptionMatches(PyExc_KeyError
))
394 if (PyErr_Occurred())
399 PyDoc_STRVAR(difference_update_doc
,
400 "Remove all elements of another set from this set.");
403 set_difference(PySetObject
*so
, PyObject
*other
)
405 PyObject
*result
, *tmp
;
406 PyObject
*otherdata
, *tgtdata
;
407 PyObject
*key
, *value
;
410 if (PyDict_Check(other
))
412 else if (PyAnySet_Check(other
))
413 otherdata
= ((PySetObject
*)other
)->data
;
415 result
= set_copy(so
);
418 tmp
= set_difference_update((PySetObject
*)result
, other
);
427 result
= make_new_set(so
->ob_type
, NULL
);
430 tgtdata
= ((PySetObject
*)result
)->data
;
432 while (PyDict_Next(so
->data
, &pos
, &key
, &value
)) {
433 if (!PyDict_Contains(otherdata
, key
)) {
434 if (PyDict_SetItem(tgtdata
, key
, Py_True
) == -1)
441 PyDoc_STRVAR(difference_doc
,
442 "Return the difference of two sets as a new set.\n\
444 (i.e. all elements that are in this set but not the other.)");
446 set_sub(PySetObject
*so
, PyObject
*other
)
448 if (!PyAnySet_Check(so
) || !PyAnySet_Check(other
)) {
449 Py_INCREF(Py_NotImplemented
);
450 return Py_NotImplemented
;
452 return set_difference(so
, other
);
456 set_isub(PySetObject
*so
, PyObject
*other
)
460 if (!PyAnySet_Check(other
)) {
461 Py_INCREF(Py_NotImplemented
);
462 return Py_NotImplemented
;
464 result
= set_difference_update(so
, other
);
469 return (PyObject
*)so
;
473 set_symmetric_difference_update(PySetObject
*so
, PyObject
*other
)
475 PyObject
*selfdata
, *otherdata
;
476 PySetObject
*otherset
= NULL
;
477 PyObject
*key
, *value
;
481 if (PyDict_Check(other
))
483 else if (PyAnySet_Check(other
))
484 otherdata
= ((PySetObject
*)other
)->data
;
486 otherset
= (PySetObject
*)make_new_set(so
->ob_type
, other
);
487 if (otherset
== NULL
)
489 otherdata
= otherset
->data
;
492 while (PyDict_Next(otherdata
, &pos
, &key
, &value
)) {
493 if (PyDict_Contains(selfdata
, key
)) {
494 if (PyDict_DelItem(selfdata
, key
) == -1) {
495 Py_XDECREF(otherset
);
499 if (PyDict_SetItem(selfdata
, key
, Py_True
) == -1) {
500 Py_XDECREF(otherset
);
505 Py_XDECREF(otherset
);
509 PyDoc_STRVAR(symmetric_difference_update_doc
,
510 "Update a set with the symmetric difference of itself and another.");
513 set_symmetric_difference(PySetObject
*so
, PyObject
*other
)
516 PyObject
*selfdata
, *otherdata
, *tgtdata
, *rv
, *otherset
;
517 PyObject
*key
, *value
;
520 if (PyDict_Check(other
))
522 else if (PyAnySet_Check(other
))
523 otherdata
= ((PySetObject
*)other
)->data
;
525 otherset
= make_new_set(so
->ob_type
, other
);
526 if (otherset
== NULL
)
528 rv
= set_symmetric_difference_update((PySetObject
*)otherset
, (PyObject
*)so
);
535 result
= (PySetObject
*)make_new_set(so
->ob_type
, NULL
);
538 tgtdata
= result
->data
;
541 while (PyDict_Next(otherdata
, &pos
, &key
, &value
)) {
542 if (!PyDict_Contains(selfdata
, key
)) {
543 if (PyDict_SetItem(tgtdata
, key
, Py_True
) == -1) {
551 while (PyDict_Next(selfdata
, &pos
, &key
, &value
)) {
552 if (!PyDict_Contains(otherdata
, key
)) {
553 if (PyDict_SetItem(tgtdata
, key
, Py_True
) == -1) {
560 return (PyObject
*)result
;
563 PyDoc_STRVAR(symmetric_difference_doc
,
564 "Return the symmetric difference of two sets as a new set.\n\
566 (i.e. all elements that are in exactly one of the sets.)");
569 set_xor(PySetObject
*so
, PyObject
*other
)
571 if (!PyAnySet_Check(so
) || !PyAnySet_Check(other
)) {
572 Py_INCREF(Py_NotImplemented
);
573 return Py_NotImplemented
;
575 return set_symmetric_difference(so
, other
);
579 set_ixor(PySetObject
*so
, PyObject
*other
)
583 if (!PyAnySet_Check(other
)) {
584 Py_INCREF(Py_NotImplemented
);
585 return Py_NotImplemented
;
587 result
= set_symmetric_difference_update(so
, other
);
592 return (PyObject
*)so
;
596 set_issubset(PySetObject
*so
, PyObject
*other
)
598 PyObject
*otherdata
, *tmp
, *result
;
599 PyObject
*key
, *value
;
602 if (!PyAnySet_Check(other
)) {
603 tmp
= make_new_set(&PySet_Type
, other
);
606 result
= set_issubset(so
, tmp
);
610 if (set_len(so
) > set_len((PySetObject
*)other
))
613 otherdata
= ((PySetObject
*)other
)->data
;
614 while (PyDict_Next(((PySetObject
*)so
)->data
, &pos
, &key
, &value
)) {
615 if (!PyDict_Contains(otherdata
, key
))
621 PyDoc_STRVAR(issubset_doc
, "Report whether another set contains this set.");
624 set_issuperset(PySetObject
*so
, PyObject
*other
)
626 PyObject
*tmp
, *result
;
628 if (!PyAnySet_Check(other
)) {
629 tmp
= make_new_set(&PySet_Type
, other
);
632 result
= set_issuperset(so
, tmp
);
636 return set_issubset((PySetObject
*)other
, (PyObject
*)so
);
639 PyDoc_STRVAR(issuperset_doc
, "Report whether this set contains another set.");
642 set_nohash(PyObject
*self
)
644 PyErr_SetString(PyExc_TypeError
, "set objects are unhashable");
649 set_nocmp(PyObject
*self
)
651 PyErr_SetString(PyExc_TypeError
, "cannot compare sets using cmp()");
656 frozenset_hash(PyObject
*self
)
658 PySetObject
*so
= (PySetObject
*)self
;
659 PyObject
*key
, *value
;
661 long hash
= 1927868237L;
666 hash
*= (PyDict_Size(so
->data
) + 1);
667 while (PyDict_Next(so
->data
, &pos
, &key
, &value
)) {
668 /* Work to increase the bit dispersion for closely spaced hash
669 values. The is important because some use cases have many
670 combinations of a small number of elements with nearby
671 hashes so that many distinct combinations collapse to only
672 a handful of distinct hash values. */
673 long h
= PyObject_Hash(key
);
674 hash
^= (h
^ (h
<< 16) ^ 89869747L) * 3644798167u;
676 hash
= hash
* 69069L + 907133923L;
684 set_richcompare(PySetObject
*v
, PyObject
*w
, int op
)
686 if(!PyAnySet_Check(w
)) {
691 PyErr_SetString(PyExc_TypeError
, "can only compare to a set");
697 return PyObject_RichCompare(((PySetObject
*)v
)->data
,
698 ((PySetObject
*)w
)->data
, op
);
700 return set_issubset((PySetObject
*)v
, w
);
702 return set_issuperset((PySetObject
*)v
, w
);
704 if (set_len(v
) >= set_len((PySetObject
*)w
))
706 return set_issubset((PySetObject
*)v
, w
);
708 if (set_len(v
) <= set_len((PySetObject
*)w
))
710 return set_issuperset((PySetObject
*)v
, w
);
712 Py_INCREF(Py_NotImplemented
);
713 return Py_NotImplemented
;
717 set_repr(PySetObject
*so
)
719 PyObject
*keys
, *result
, *listrepr
;
721 keys
= PyDict_Keys(so
->data
);
724 listrepr
= PyObject_Repr(keys
);
726 if (listrepr
== NULL
)
729 result
= PyString_FromFormat("%s(%s)", so
->ob_type
->tp_name
,
730 PyString_AS_STRING(listrepr
));
736 set_tp_print(PySetObject
*so
, FILE *fp
, int flags
)
738 PyObject
*key
, *value
;
740 char *emit
= ""; /* No separator emitted on first pass */
741 char *separator
= ", ";
743 fprintf(fp
, "%s([", so
->ob_type
->tp_name
);
744 while (PyDict_Next(so
->data
, &pos
, &key
, &value
)) {
747 if (PyObject_Print(key
, fp
, 0) != 0)
755 set_clear(PySetObject
*so
)
757 PyDict_Clear(so
->data
);
762 PyDoc_STRVAR(clear_doc
, "Remove all elements from this set.");
765 set_add(PySetObject
*so
, PyObject
*item
)
767 if (PyDict_SetItem(so
->data
, item
, Py_True
) == -1)
772 PyDoc_STRVAR(add_doc
,
773 "Add an element to a set.\n\
775 This has no effect if the element is already present.");
778 set_remove(PySetObject
*so
, PyObject
*item
)
780 PyObject
*tmp
, *result
;
782 if (PyType_IsSubtype(item
->ob_type
, &PySet_Type
)) {
783 tmp
= frozenset_dict_wrapper(((PySetObject
*)(item
))->data
);
786 result
= set_remove(so
, tmp
);
791 if (PyDict_DelItem(so
->data
, item
) == -1)
796 PyDoc_STRVAR(remove_doc
,
797 "Remove an element from a set; it must be a member.\n\
799 If the element is not a member, raise a KeyError.");
802 set_discard(PySetObject
*so
, PyObject
*item
)
804 PyObject
*tmp
, *result
;
806 if (PyType_IsSubtype(item
->ob_type
, &PySet_Type
)) {
807 tmp
= frozenset_dict_wrapper(((PySetObject
*)(item
))->data
);
810 result
= set_discard(so
, tmp
);
815 if (PyDict_DelItem(so
->data
, item
) == -1) {
816 if (!PyErr_ExceptionMatches(PyExc_KeyError
))
823 PyDoc_STRVAR(discard_doc
,
824 "Remove an element from a set if it is a member.\n\
826 If the element is not a member, do nothing.");
829 set_pop(PySetObject
*so
)
831 PyObject
*key
, *value
;
834 if (!PyDict_Next(so
->data
, &pos
, &key
, &value
)) {
835 PyErr_SetString(PyExc_KeyError
, "pop from an empty set");
839 if (PyDict_DelItem(so
->data
, key
) == -1) {
846 PyDoc_STRVAR(pop_doc
, "Remove and return an arbitrary set element.");
849 set_reduce(PySetObject
*so
)
851 PyObject
*keys
=NULL
, *args
=NULL
, *result
=NULL
;
853 keys
= PyDict_Keys(so
->data
);
856 args
= PyTuple_Pack(1, keys
);
859 result
= PyTuple_Pack(2, so
->ob_type
, args
);
866 PyDoc_STRVAR(reduce_doc
, "Return state information for pickling.");
869 set_init(PySetObject
*self
, PyObject
*args
, PyObject
*kwds
)
871 PyObject
*iterable
= NULL
;
874 if (!PyAnySet_Check(self
))
876 if (!PyArg_UnpackTuple(args
, self
->ob_type
->tp_name
, 0, 1, &iterable
))
878 PyDict_Clear(self
->data
);
880 if (iterable
== NULL
)
882 result
= set_update(self
, iterable
);
883 if (result
!= NULL
) {
890 static PySequenceMethods set_as_sequence
= {
891 (inquiry
)set_len
, /* sq_length */
897 0, /* sq_ass_slice */
898 (objobjproc
)set_contains
, /* sq_contains */
901 /* set object ********************************************************/
903 static PyMethodDef set_methods
[] = {
904 {"add", (PyCFunction
)set_add
, METH_O
,
906 {"clear", (PyCFunction
)set_clear
, METH_NOARGS
,
908 {"__contains__",(PyCFunction
)set_direct_contains
, METH_O
| METH_COEXIST
,
910 {"copy", (PyCFunction
)set_copy
, METH_NOARGS
,
912 {"discard", (PyCFunction
)set_discard
, METH_O
,
914 {"difference", (PyCFunction
)set_difference
, METH_O
,
916 {"difference_update", (PyCFunction
)set_difference_update
, METH_O
,
917 difference_update_doc
},
918 {"intersection",(PyCFunction
)set_intersection
, METH_O
,
920 {"intersection_update",(PyCFunction
)set_intersection_update
, METH_O
,
921 intersection_update_doc
},
922 {"issubset", (PyCFunction
)set_issubset
, METH_O
,
924 {"issuperset", (PyCFunction
)set_issuperset
, METH_O
,
926 {"pop", (PyCFunction
)set_pop
, METH_NOARGS
,
928 {"__reduce__", (PyCFunction
)set_reduce
, METH_NOARGS
,
930 {"remove", (PyCFunction
)set_remove
, METH_O
,
932 {"symmetric_difference",(PyCFunction
)set_symmetric_difference
, METH_O
,
933 symmetric_difference_doc
},
934 {"symmetric_difference_update",(PyCFunction
)set_symmetric_difference_update
, METH_O
,
935 symmetric_difference_update_doc
},
936 {"union", (PyCFunction
)set_union
, METH_O
,
938 {"update", (PyCFunction
)set_update
, METH_O
,
940 {NULL
, NULL
} /* sentinel */
943 static PyNumberMethods set_as_number
= {
945 (binaryfunc
)set_sub
, /*nb_subtract*/
958 (binaryfunc
)set_and
, /*nb_and*/
959 (binaryfunc
)set_xor
, /*nb_xor*/
960 (binaryfunc
)set_or
, /*nb_or*/
967 0, /*nb_inplace_add*/
968 (binaryfunc
)set_isub
, /*nb_inplace_subtract*/
969 0, /*nb_inplace_multiply*/
970 0, /*nb_inplace_divide*/
971 0, /*nb_inplace_remainder*/
972 0, /*nb_inplace_power*/
973 0, /*nb_inplace_lshift*/
974 0, /*nb_inplace_rshift*/
975 (binaryfunc
)set_iand
, /*nb_inplace_and*/
976 (binaryfunc
)set_ixor
, /*nb_inplace_xor*/
977 (binaryfunc
)set_ior
, /*nb_inplace_or*/
980 PyDoc_STRVAR(set_doc
,
981 "set(iterable) --> set object\n\
983 Build an unordered collection.");
985 PyTypeObject PySet_Type
= {
986 PyObject_HEAD_INIT(&PyType_Type
)
989 sizeof(PySetObject
), /* tp_basicsize */
992 (destructor
)set_dealloc
, /* tp_dealloc */
993 (printfunc
)set_tp_print
, /* tp_print */
996 (cmpfunc
)set_nocmp
, /* tp_compare */
997 (reprfunc
)set_repr
, /* tp_repr */
998 &set_as_number
, /* tp_as_number */
999 &set_as_sequence
, /* tp_as_sequence */
1000 0, /* tp_as_mapping */
1001 set_nohash
, /* tp_hash */
1004 PyObject_GenericGetAttr
, /* tp_getattro */
1005 0, /* tp_setattro */
1006 0, /* tp_as_buffer */
1007 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
1008 Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
1009 set_doc
, /* tp_doc */
1010 0, /* tp_traverse */
1012 (richcmpfunc
)set_richcompare
, /* tp_richcompare */
1013 offsetof(PySetObject
, weakreflist
), /* tp_weaklistoffset */
1014 (getiterfunc
)set_iter
, /* tp_iter */
1015 0, /* tp_iternext */
1016 set_methods
, /* tp_methods */
1021 0, /* tp_descr_get */
1022 0, /* tp_descr_set */
1023 0, /* tp_dictoffset */
1024 (initproc
)set_init
, /* tp_init */
1025 PyType_GenericAlloc
, /* tp_alloc */
1026 set_new
, /* tp_new */
1027 PyObject_Del
, /* tp_free */
1030 /* frozenset object ********************************************************/
1033 static PyMethodDef frozenset_methods
[] = {
1034 {"__contains__",(PyCFunction
)set_direct_contains
, METH_O
| METH_COEXIST
,
1036 {"copy", (PyCFunction
)frozenset_copy
, METH_NOARGS
,
1038 {"difference", (PyCFunction
)set_difference
, METH_O
,
1040 {"intersection",(PyCFunction
)set_intersection
, METH_O
,
1042 {"issubset", (PyCFunction
)set_issubset
, METH_O
,
1044 {"issuperset", (PyCFunction
)set_issuperset
, METH_O
,
1046 {"__reduce__", (PyCFunction
)set_reduce
, METH_NOARGS
,
1048 {"symmetric_difference",(PyCFunction
)set_symmetric_difference
, METH_O
,
1049 symmetric_difference_doc
},
1050 {"union", (PyCFunction
)set_union
, METH_O
,
1052 {NULL
, NULL
} /* sentinel */
1055 static PyNumberMethods frozenset_as_number
= {
1057 (binaryfunc
)set_sub
, /*nb_subtract*/
1070 (binaryfunc
)set_and
, /*nb_and*/
1071 (binaryfunc
)set_xor
, /*nb_xor*/
1072 (binaryfunc
)set_or
, /*nb_or*/
1075 PyDoc_STRVAR(frozenset_doc
,
1076 "frozenset(iterable) --> frozenset object\n\
1078 Build an immutable unordered collection.");
1080 PyTypeObject PyFrozenSet_Type
= {
1081 PyObject_HEAD_INIT(&PyType_Type
)
1083 "frozenset", /* tp_name */
1084 sizeof(PySetObject
), /* tp_basicsize */
1085 0, /* tp_itemsize */
1087 (destructor
)set_dealloc
, /* tp_dealloc */
1088 (printfunc
)set_tp_print
, /* tp_print */
1091 (cmpfunc
)set_nocmp
, /* tp_compare */
1092 (reprfunc
)set_repr
, /* tp_repr */
1093 &frozenset_as_number
, /* tp_as_number */
1094 &set_as_sequence
, /* tp_as_sequence */
1095 0, /* tp_as_mapping */
1096 frozenset_hash
, /* tp_hash */
1099 PyObject_GenericGetAttr
, /* tp_getattro */
1100 0, /* tp_setattro */
1101 0, /* tp_as_buffer */
1102 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_CHECKTYPES
|
1103 Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_WEAKREFS
, /* tp_flags */
1104 frozenset_doc
, /* tp_doc */
1105 0, /* tp_traverse */
1107 (richcmpfunc
)set_richcompare
, /* tp_richcompare */
1108 offsetof(PySetObject
, weakreflist
), /* tp_weaklistoffset */
1109 (getiterfunc
)set_iter
, /* tp_iter */
1110 0, /* tp_iternext */
1111 frozenset_methods
, /* tp_methods */
1116 0, /* tp_descr_get */
1117 0, /* tp_descr_set */
1118 0, /* tp_dictoffset */
1120 PyType_GenericAlloc
, /* tp_alloc */
1121 frozenset_new
, /* tp_new */
1122 PyObject_Del
, /* tp_free */