Keep track of a type's subclasses (subtypes), in tp_subclasses, which
is a list of weak references to types (new-style classes).  Make this
accessible to Python as the function __subclasses__ which returns a
list of types -- we don't want Python programmers to be able to
manipulate the raw list.

In order to make this possible, I also had to add weak reference
support to type objects.

This will eventually be used together with a trap on attribute
assignment for dynamic classes for a major speed-up without losing the
dynamic properties of types: when a __foo__ method is added to a
class, the class and all its subclasses will get an appropriate tp_foo
slot function.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 0ec8175..c068548 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1118,20 +1118,52 @@
 	/* Assert this is a heap-allocated type object */
 	assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
 	_PyObject_GC_UNTRACK(type);
+	PyObject_ClearWeakRefs((PyObject *)type);
 	et = (etype *)type;
 	Py_XDECREF(type->tp_base);
 	Py_XDECREF(type->tp_dict);
 	Py_XDECREF(type->tp_bases);
 	Py_XDECREF(type->tp_mro);
 	Py_XDECREF(type->tp_defined);
+	Py_XDECREF(type->tp_subclasses);
 	Py_XDECREF(et->name);
 	Py_XDECREF(et->slots);
 	type->ob_type->tp_free((PyObject *)type);
 }
 
+static PyObject *
+type_subclasses(PyTypeObject *type, PyObject *args_ignored)
+{
+	PyObject *list, *raw, *ref;
+	int i, n;
+
+	list = PyList_New(0);
+	if (list == NULL)
+		return NULL;
+	raw = type->tp_subclasses;
+	if (raw == NULL)
+		return list;
+	assert(PyList_Check(raw));
+	n = PyList_GET_SIZE(raw);
+	for (i = 0; i < n; i++) {
+		ref = PyList_GET_ITEM(raw, i);
+		assert(PyWeakref_CheckRef(res));
+		ref = PyWeakref_GET_OBJECT(ref);
+		if (ref != Py_None) {
+			if (PyList_Append(list, ref) < 0) {
+				Py_DECREF(list);
+				return NULL;
+			}
+		}
+	}
+	return list;
+}
+
 static PyMethodDef type_methods[] = {
 	{"mro", (PyCFunction)mro_external, METH_NOARGS,
 	 "mro() -> list\nreturn a type's method resolution order"},
+	{"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS,
+	 "__subclasses__() -> list of immediate subclasses"},
 	{0}
 };
 
@@ -1162,6 +1194,7 @@
 	VISIT(type->tp_mro);
 	VISIT(type->tp_bases);
 	VISIT(type->tp_base);
+	VISIT(type->tp_subclasses);
 	VISIT(et->slots);
 
 #undef VISIT
@@ -1192,6 +1225,7 @@
 	CLEAR(type->tp_mro);
 	CLEAR(type->tp_bases);
 	CLEAR(type->tp_base);
+	CLEAR(type->tp_subclasses);
 	CLEAR(et->slots);
 
 	if (type->tp_doc != NULL) {
@@ -1237,7 +1271,7 @@
 	(traverseproc)type_traverse,		/* tp_traverse */
 	(inquiry)type_clear,			/* tp_clear */
 	0,					/* tp_richcompare */
-	0,					/* tp_weaklistoffset */
+	offsetof(PyTypeObject, tp_weaklist),	/* tp_weaklistoffset */
 	0,					/* tp_iter */
 	0,					/* tp_iternext */
 	type_methods,				/* tp_methods */
@@ -1741,6 +1775,7 @@
 }
 
 staticforward int add_operators(PyTypeObject *);
+staticforward int add_subclass(PyTypeObject *base, PyTypeObject *type);
 
 int
 PyType_Ready(PyTypeObject *type)
@@ -1858,6 +1893,15 @@
 			type->tp_as_mapping = base->tp_as_mapping;
 	}
 
+	/* Link into each base class's list of subclasses */
+	bases = type->tp_bases;
+	n = PyTuple_GET_SIZE(bases);
+	for (i = 0; i < n; i++) {
+		base = (PyTypeObject *) PyTuple_GET_ITEM(bases, i);
+		if (add_subclass((PyTypeObject *)base, type) < 0)
+			goto error;
+	}
+
 	/* All done -- set the ready flag */
 	assert(type->tp_dict != NULL);
 	type->tp_flags =
@@ -1869,6 +1913,32 @@
 	return -1;
 }
 
+static int
+add_subclass(PyTypeObject *base, PyTypeObject *type)
+{
+	int i;
+	PyObject *list, *ref, *new;
+
+	list = base->tp_subclasses;
+	if (list == NULL) {
+		base->tp_subclasses = list = PyList_New(0);
+		if (list == NULL)
+			return -1;
+	}
+	assert(PyList_Check(list));
+	new = PyWeakref_NewRef((PyObject *)type, NULL);
+	i = PyList_GET_SIZE(list);
+	while (--i >= 0) {
+		ref = PyList_GET_ITEM(list, i);
+		assert(PyWeakref_CheckRef(ref));
+		if (PyWeakref_GET_OBJECT(ref) == Py_None)
+			return PyList_SetItem(list, i, new);
+	}
+	i = PyList_Append(list, new);
+	Py_DECREF(new);
+	return i;
+}
+
 
 /* Generic wrappers for overloadable 'operators' such as __getitem__ */