@@ -311,9 +311,6 @@ set_table_resize(PySetObject *so, int minused)
311311 return 0 ;
312312}
313313
314- /*** Internal functions (derived from public dictionary api functions ) ***/
315-
316-
317314/* CAUTION: set_add_internal() must guarantee that it won't resize the table */
318315static int
319316set_add_internal (register PySetObject * so , PyObject * key )
@@ -435,10 +432,10 @@ set_clear_internal(PySetObject *so)
435432/*
436433 * Iterate over a set table. Use like so:
437434 *
438- * int i ;
435+ * int pos ;
439436 * PyObject *key;
440- * i = 0; # important! i should not otherwise be changed by you
441- * while (set_next_internal(yourset, &i , &key)) {
437+ * pos = 0; # important! pos should not otherwise be changed by you
438+ * while (set_next_internal(yourset, &pos , &key)) {
442439 * Refer to borrowed reference in key.
443440 * }
444441 *
@@ -467,14 +464,13 @@ set_next_internal(PySetObject *so, int *pos, PyObject **key)
467464 return 1 ;
468465}
469466
470- /* Methods */
471-
472467static int
473468set_merge_internal (PySetObject * so , PyObject * otherset )
474469{
475- register PySetObject * other ;
470+ PySetObject * other ;
476471 register int i ;
477- setentry * entry ;
472+ register setentry * entry , * othertable ;
473+ register int othermask ;
478474
479475 assert (PyAnySet_Check (so ));
480476 assert (PyAnySet_Check (otherset ));
@@ -491,8 +487,10 @@ set_merge_internal(PySetObject *so, PyObject *otherset)
491487 if (set_table_resize (so , (so -> used + other -> used )* 2 ) != 0 )
492488 return -1 ;
493489 }
494- for (i = 0 ; i <= other -> mask ; i ++ ) {
495- entry = & other -> table [i ];
490+ othermask = other -> mask ;
491+ othertable = other -> table ;
492+ for (i = 0 ; i <= othermask ; i ++ ) {
493+ entry = & othertable [i ];
496494 if (entry -> key != NULL &&
497495 entry -> key != dummy ) {
498496 Py_INCREF (entry -> key );
@@ -517,9 +515,9 @@ set_contains_internal(PySetObject *so, PyObject *key)
517515 return key != NULL && key != dummy ;
518516}
519517
520- static PyTypeObject PySetIter_Type ; /* Forward */
518+ /***** Set iterator types ********************************************* */
521519
522- /* Set iterator types */
520+ static PyTypeObject PySetIter_Type ; /* Forward */
523521
524522typedef struct {
525523 PyObject_HEAD
@@ -647,41 +645,52 @@ static PyTypeObject PySetIter_Type = {
647645 All rights reserved.
648646*/
649647
650- static PyObject *
651- set_update (PySetObject * so , PyObject * other )
648+ static int
649+ set_len (PyObject * so )
650+ {
651+ return ((PySetObject * )so )-> used ;
652+ }
653+
654+ static int
655+ set_update_internal (PySetObject * so , PyObject * other )
652656{
653657 PyObject * key , * it ;
654658
655- if (PyAnySet_Check (other )) {
656- if (set_merge_internal (so , other ) == -1 )
657- return NULL ;
658- Py_RETURN_NONE ;
659- }
659+ if (PyAnySet_Check (other ))
660+ return set_merge_internal (so , other );
660661
661662 if (PyDict_Check (other )) {
662663 PyObject * key , * value ;
663664 int pos = 0 ;
664665 while (PyDict_Next (other , & pos , & key , & value )) {
665666 if (set_add_internal (so , key ) == -1 )
666- return NULL ;
667+ return -1 ;
667668 }
668- Py_RETURN_NONE ;
669+ return 0 ;
669670 }
670671
671672 it = PyObject_GetIter (other );
672673 if (it == NULL )
673- return NULL ;
674+ return -1 ;
674675
675676 while ((key = PyIter_Next (it )) != NULL ) {
676677 if (set_add_internal (so , key ) == -1 ) {
677678 Py_DECREF (it );
678679 Py_DECREF (key );
679- return NULL ;
680+ return -1 ;
680681 }
681682 Py_DECREF (key );
682683 }
683684 Py_DECREF (it );
684685 if (PyErr_Occurred ())
686+ return -1 ;
687+ return 0 ;
688+ }
689+
690+ static PyObject *
691+ set_update (PySetObject * so , PyObject * other )
692+ {
693+ if (set_update_internal (so , other ) == -1 )
685694 return NULL ;
686695 Py_RETURN_NONE ;
687696}
@@ -692,7 +701,6 @@ PyDoc_STRVAR(update_doc,
692701static PyObject *
693702make_new_set (PyTypeObject * type , PyObject * iterable )
694703{
695- PyObject * tmp ;
696704 register PySetObject * so = NULL ;
697705
698706 if (dummy == NULL ) { /* Auto-initialize dummy */
@@ -712,37 +720,51 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
712720 so -> weakreflist = NULL ;
713721
714722 if (iterable != NULL ) {
715- tmp = set_update (so , iterable );
716- if (tmp == NULL ) {
723+ if (set_update_internal (so , iterable ) == -1 ) {
717724 Py_DECREF (so );
718725 return NULL ;
719726 }
720- Py_DECREF (tmp );
721727 }
722728
723729 return (PyObject * )so ;
724730}
725731
732+ /* The empty frozenset is a singleton */
733+ static PyObject * emptyfrozenset = NULL ;
734+
726735static PyObject *
727736frozenset_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
728737{
729- PyObject * iterable = NULL ;
730- static PyObject * emptyfrozenset = NULL ;
738+ PyObject * iterable = NULL , * result ;
731739
732740 if (!PyArg_UnpackTuple (args , type -> tp_name , 0 , 1 , & iterable ))
733741 return NULL ;
734- if (iterable == NULL ) {
735- if (type == & PyFrozenSet_Type ) {
736- if (emptyfrozenset == NULL )
737- emptyfrozenset = make_new_set (type , NULL );
738- Py_INCREF (emptyfrozenset );
739- return emptyfrozenset ;
742+
743+ if (type != & PyFrozenSet_Type )
744+ return make_new_set (type , iterable );
745+
746+ if (iterable != NULL ) {
747+ /* frozenset(f) is idempotent */
748+ if (PyFrozenSet_CheckExact (iterable )) {
749+ Py_INCREF (iterable );
750+ return iterable ;
740751 }
741- } else if (PyFrozenSet_CheckExact (iterable )) {
742- Py_INCREF (iterable );
743- return iterable ;
752+ result = make_new_set (type , iterable );
753+ if (result == NULL || set_len (result ))
754+ return result ;
755+ Py_DECREF (result );
744756 }
745- return make_new_set (type , iterable );
757+ /* The empty frozenset is a singleton */
758+ if (emptyfrozenset == NULL )
759+ emptyfrozenset = make_new_set (type , NULL );
760+ Py_XINCREF (emptyfrozenset );
761+ return emptyfrozenset ;
762+ }
763+
764+ void
765+ PySet_Fini (void )
766+ {
767+ Py_XDECREF (emptyfrozenset );
746768}
747769
748770static PyObject *
@@ -786,12 +808,6 @@ set_traverse(PySetObject *so, visitproc visit, void *arg)
786808 return 0 ;
787809}
788810
789- static int
790- set_len (PyObject * so )
791- {
792- return ((PySetObject * )so )-> used ;
793- }
794-
795811/* set_swap_bodies() switches the contents of any two sets by moving their
796812 internal data pointers and, if needed, copying the internal smalltables.
797813 Semantically equivalent to:
@@ -892,17 +908,14 @@ static PyObject *
892908set_union (PySetObject * so , PyObject * other )
893909{
894910 PySetObject * result ;
895- PyObject * rv ;
896911
897912 result = (PySetObject * )set_copy (so );
898913 if (result == NULL )
899914 return NULL ;
900- rv = set_update (result , other );
901- if (rv == NULL ) {
915+ if (set_update_internal (result , other ) == -1 ) {
902916 Py_DECREF (result );
903917 return NULL ;
904918 }
905- Py_DECREF (rv );
906919 return (PyObject * )result ;
907920}
908921
@@ -924,16 +937,12 @@ set_or(PySetObject *so, PyObject *other)
924937static PyObject *
925938set_ior (PySetObject * so , PyObject * other )
926939{
927- PyObject * result ;
928-
929940 if (!PyAnySet_Check (other )) {
930941 Py_INCREF (Py_NotImplemented );
931942 return Py_NotImplemented ;
932943 }
933- result = set_update (so , other );
934- if (result == NULL )
944+ if (set_update_internal (so , other ) == -1 )
935945 return NULL ;
936- Py_DECREF (result );
937946 Py_INCREF (so );
938947 return (PyObject * )so ;
939948}
@@ -1553,7 +1562,6 @@ static int
15531562set_init (PySetObject * self , PyObject * args , PyObject * kwds )
15541563{
15551564 PyObject * iterable = NULL ;
1556- PyObject * result ;
15571565
15581566 if (!PyAnySet_Check (self ))
15591567 return -1 ;
@@ -1563,12 +1571,7 @@ set_init(PySetObject *self, PyObject *args, PyObject *kwds)
15631571 self -> hash = -1 ;
15641572 if (iterable == NULL )
15651573 return 0 ;
1566- result = set_update (self , iterable );
1567- if (result != NULL ) {
1568- Py_DECREF (result );
1569- return 0 ;
1570- }
1571- return -1 ;
1574+ return set_update_internal (self , iterable );
15721575}
15731576
15741577static PySequenceMethods set_as_sequence = {
0 commit comments