Patch #1623563: allow __class__ assignment for classes with __slots__.
The old and the new class are still required to have the same slot
names, but the order in which they are specified is not relevant.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 64abe5a..64003fc 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1844,8 +1844,11 @@
 			}
 		}
 
-		/* Copy slots into yet another tuple, demangling names */
-		newslots = PyTuple_New(nslots - add_dict - add_weak);
+		/* Copy slots into a list, mangle names and sort them.
+		   Sorted names are needed for __class__ assignment.
+		   Convert them back to tuple at the end.
+		*/
+		newslots = PyList_New(nslots - add_dict - add_weak);
 		if (newslots == NULL)
 			goto bad_slots;
 		for (i = j = 0; i < nslots; i++) {
@@ -1858,13 +1861,23 @@
 			tmp =_Py_Mangle(name, tmp);
 			if (!tmp)
 			    goto bad_slots;
-			PyTuple_SET_ITEM(newslots, j, tmp);
+			PyList_SET_ITEM(newslots, j, tmp);
 			j++;
 		}
 		assert(j == nslots - add_dict - add_weak);
 		nslots = j;
 		Py_DECREF(slots);
-		slots = newslots;
+		if (PyList_Sort(newslots) == -1) {
+			Py_DECREF(bases);
+			Py_DECREF(newslots);
+			return NULL;
+		}
+		slots = PyList_AsTuple(newslots);
+		Py_DECREF(newslots);
+		if (slots == NULL) {
+			Py_DECREF(bases);
+			return NULL;
+		}
 
 		/* Secondary bases may provide weakrefs or dict */
 		if (nbases > 1 &&
@@ -2481,6 +2494,7 @@
 {
 	PyTypeObject *base = a->tp_base;
 	Py_ssize_t size;
+	PyObject *slots_a, *slots_b;
 
 	if (base != b->tp_base)
 		return 0;
@@ -2491,6 +2505,15 @@
 		size += sizeof(PyObject *);
 	if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size)
 		size += sizeof(PyObject *);
+
+	/* Check slots compliance */
+	slots_a = ((PyHeapTypeObject *)a)->ht_slots;
+	slots_b = ((PyHeapTypeObject *)b)->ht_slots;
+	if (slots_a && slots_b) {
+		if (PyObject_Compare(slots_a, slots_b) != 0)
+			return 0;
+		size += sizeof(PyObject *) * PyTuple_GET_SIZE(slots_a);
+	}
 	return size == a->tp_basicsize && size == b->tp_basicsize;
 }