Commits

Raymond Hettinger  committed f0202c3

Add the same dummy type that is used in dictionaries.

  • Participants
  • Parent commits 41d459f

Comments (0)

Files changed (1)

File Objects/setobject.c

 #define PERTURB_SHIFT 5
 
 /* Object used as dummy key to fill deleted entries */
-static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */
+
+static PyObject _dummy_struct;
+
+#define dummy (&_dummy_struct)
 
 #ifdef Py_REF_DEBUG
 PyObject *
     Py_ssize_t i;
     int is_oldtable_malloced;
     setentry small_copy[PySet_MINSIZE];
-    PyObject *dummy_entry;
 
     assert(minused >= 0);
 
 
     /* Copy the data over; this is refcount-neutral for active entries;
        dummy entries aren't copied over, of course */
-    dummy_entry = dummy;
     for (entry = oldtable; i > 0; entry++) {
-        if (entry->key != NULL && entry->key != dummy_entry) {
-            /* ACTIVE */
+        if (entry->key != NULL && entry->key != dummy) {
             --i;
             set_insert_clean(so, entry->key, entry->hash);
         }
 {
     PySetObject *other;
     PyObject *key;
-    PyObject *dummy_entry;
     Py_hash_t hash;
     Py_ssize_t i;
     setentry *entry;
        if (set_table_resize(so, (so->used + other->used)*2) != 0)
            return -1;
     }
-    dummy_entry = dummy;
     for (i = 0; i <= other->mask; i++) {
         entry = &other->table[i];
         key = entry->key;
         hash = entry->hash;
         if (key != NULL &&
-            key != dummy_entry) {
+            key != dummy) {
             Py_INCREF(key);
             if (set_insert_key(so, key, hash) == -1) {
                 Py_DECREF(key);
 {
     PySetObject *so = NULL;
 
-    if (dummy == NULL) { /* Auto-initialize dummy */
-        dummy = PyUnicode_FromString("<dummy key>");
-        if (dummy == NULL)
-            return NULL;
-    }
-
     /* create PySetObject structure */
     if (numfree &&
         (type == &PySet_Type  ||  type == &PyFrozenSet_Type)) {
 PySet_Fini(void)
 {
     PySet_ClearFreeList();
-    Py_CLEAR(dummy);
     Py_CLEAR(emptyfrozenset);
 }
 
 #undef assertRaises
 
 #endif
+
+/***** Dummy Struct  *************************************************/
+
+static PyObject *
+dummy_repr(PyObject *op)
+{
+    return PyUnicode_FromString("<dummy key>");
+}
+
+static void
+dummy_dealloc(PyObject* ignore)
+{
+    Py_FatalError("deallocating <dummy key>");
+}
+
+static PyTypeObject _PySetDummy_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)
+    "<dummy key> type",
+    0,
+    0,
+    dummy_dealloc,      /*tp_dealloc*/ /*never called*/
+    0,                  /*tp_print*/
+    0,                  /*tp_getattr*/
+    0,                  /*tp_setattr*/
+    0,                  /*tp_reserved*/
+    dummy_repr,         /*tp_repr*/
+    0,                  /*tp_as_number*/
+    0,                  /*tp_as_sequence*/
+    0,                  /*tp_as_mapping*/
+    0,                  /*tp_hash */
+    0,                  /*tp_call */
+    0,                  /*tp_str */
+    0,                  /*tp_getattro */
+    0,                  /*tp_setattro */
+    0,                  /*tp_as_buffer */
+    Py_TPFLAGS_DEFAULT, /*tp_flags */
+};
+
+static PyObject _dummy_struct = {
+  _PyObject_EXTRA_INIT
+  2, &_PySetDummy_Type
+};
+