SF 569257 -- Name mangle double underscored variable names in __slots__.
diff --git a/Include/Python.h b/Include/Python.h
index 548ac75..ff21ad1 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -119,6 +119,10 @@
 
 #include "abstract.h"
 
+/* _Py_Mangle is defined in compile.c */
+extern DL_IMPORT(int) _Py_Mangle(char *p, char *name, \
+				 char *buffer, size_t maxlen);
+
 /* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */
 #define PyArg_GetInt(v, a)	PyArg_Parse((v), "i", (a))
 
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 2129a7b..dca8ea1 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1060,6 +1060,24 @@
     vereq(x.b, 2)
     vereq(x.c, 3)
 
+    class C4(object):
+        """Validate name mangling"""
+        __slots__ = ['__a']
+        def __init__(self, value):
+            self.__a = value
+        def get(self):
+            return self.__a
+    x = C4(5)
+    verify(not hasattr(x, '__dict__'))
+    verify(not hasattr(x, '__a'))
+    vereq(x.get(), 5)
+    try:
+        x.__a = 6
+    except AttributeError:
+        pass
+    else:
+        raise TestFailed, "Double underscored names not mangled"
+
     # Make sure slot names are proper identifiers
     try:
         class C(object):
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 7918af0..47613f5 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1001,7 +1001,8 @@
 {
 	PyObject *name, *bases, *dict;
 	static char *kwlist[] = {"name", "bases", "dict", 0};
-	PyObject *slots, *tmp;
+	static char buffer[256];
+	PyObject *slots, *tmp, *newslots;
 	PyTypeObject *type, *base, *tmptype, *winner;
 	etype *et;
 	PyMemberDef *mp;
@@ -1115,6 +1116,25 @@
 				return NULL;
 			}
 		}
+
+		newslots = PyTuple_New(nslots);
+		if (newslots == NULL)
+			return NULL;
+		for (i = 0; i < nslots; i++) {
+			tmp = PyTuple_GET_ITEM(slots, i);
+			if (_Py_Mangle(PyString_AS_STRING(name),
+				PyString_AS_STRING(tmp),
+				buffer, sizeof(buffer)))
+			{
+				tmp = PyString_FromString(buffer);
+			} else {
+				Py_INCREF(tmp);
+			}
+			PyTuple_SET_ITEM(newslots, i, tmp);
+		}
+		Py_DECREF(slots);
+		slots = newslots;
+
 	}
 	if (slots != NULL) {
 		/* See if *this* class defines __getstate__ */
diff --git a/Python/compile.c b/Python/compile.c
index b0e125d..fa53b1e 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -928,8 +928,8 @@
 	return com_add(c, c->c_names, c->c_name_dict, v);
 }
 
-static int
-mangle(char *p, char *name, char *buffer, size_t maxlen)
+int
+_Py_Mangle(char *p, char *name, char *buffer, size_t maxlen)
 {
 	/* Name mangling: __private becomes _classname__private.
 	   This is independent from how the name is used. */
@@ -963,7 +963,7 @@
 	int i;
 	char buffer[MANGLE_LEN];
 
-	if (mangle(c->c_private, name, buffer, sizeof(buffer)))
+	if (_Py_Mangle(c->c_private, name, buffer, sizeof(buffer)))
 		name = buffer;
 	if (name == NULL || (v = PyString_InternFromString(name)) == NULL) {
 		c->c_errors++;
@@ -1000,7 +1000,7 @@
 	int op = STOP_CODE;
 	char buffer[MANGLE_LEN];
 
-	if (mangle(c->c_private, name, buffer, sizeof(buffer)))
+	if (_Py_Mangle(c->c_private, name, buffer, sizeof(buffer)))
 		name = buffer;
 	if (name == NULL || (v = PyString_InternFromString(name)) == NULL) {
 		c->c_errors++;
@@ -4956,7 +4956,7 @@
 	PyObject *v;
 	int flags;
 
-	if (mangle(st->st_private, name, buffer, sizeof(buffer)))
+	if (_Py_Mangle(st->st_private, name, buffer, sizeof(buffer)))
 		name = buffer;
 	v = PyDict_GetItemString(st->st_cur->ste_symbols, name);
 	if (v == NULL) {
@@ -4977,7 +4977,7 @@
 	char buffer[MANGLE_LEN];
 	int ret;
 
-	if (mangle(st->st_private, name, buffer, sizeof(buffer)))
+	if (_Py_Mangle(st->st_private, name, buffer, sizeof(buffer)))
 		name = buffer;
 	if ((s = PyString_InternFromString(name)) == NULL)
 		return -1;