Fix SF bug #486144: Uninitialized __slot__ vrbl is None.

There's now a new structmember code, T_OBJECT_EX, which is used for
all __slot__ variables (except __weakref__, which has special behavior
anyway).  This new code raises AttributeError when the variable is
NULL rather than converting NULL to None.
diff --git a/Include/structmember.h b/Include/structmember.h
index 2c9f41d..98eccc0 100644
--- a/Include/structmember.h
+++ b/Include/structmember.h
@@ -68,6 +68,10 @@
 #define T_PSTRING_INPLACE	15
 #endif /* macintosh */
 
+#define T_OBJECT_EX	16	/* Like T_OBJECT, but raises AttributeError
+				   when the value is NULL, instead of
+				   converting to None. */
+
 /* Flags */
 #define READONLY	1
 #define RO		READONLY		/* Shorthand */
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index d76013e..48d1138 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -978,19 +978,21 @@
         __slots__ = ['a']
     x = C1()
     verify(not hasattr(x, "__dict__"))
-    vereq(x.a, None)
+    verify(not hasattr(x, "a"))
     x.a = 1
     vereq(x.a, 1)
+    x.a = None
+    veris(x.a, None)
     del x.a
-    vereq(x.a, None)
+    verify(not hasattr(x, "a"))
 
     class C3(object):
         __slots__ = ['a', 'b', 'c']
     x = C3()
     verify(not hasattr(x, "__dict__"))
-    verify(x.a is None)
-    verify(x.b is None)
-    verify(x.c is None)
+    verify(not hasattr(x, 'a'))
+    verify(not hasattr(x, 'b'))
+    verify(not hasattr(x, 'c'))
     x.a = 1
     x.b = 2
     x.c = 3
diff --git a/Python/structmember.c b/Python/structmember.c
index aa0ea9f..34310b8 100644
--- a/Python/structmember.c
+++ b/Python/structmember.c
@@ -129,6 +129,12 @@
 			v = Py_None;
 		Py_INCREF(v);
 		break;
+	case T_OBJECT_EX:
+		v = *(PyObject **)addr;
+		if (v == NULL)
+			PyErr_SetString(PyExc_AttributeError, l->name);
+		Py_XINCREF(v);
+		break;
 	default:
 		PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
 		v = NULL;
@@ -175,7 +181,7 @@
 		PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
 		return -1;
 	}
-	if (v == NULL && l->type != T_OBJECT) {
+	if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) {
 		PyErr_SetString(PyExc_TypeError,
 				"can't delete numeric/char attribute");
 		return -1;
@@ -246,6 +252,7 @@
 		}
 		break;
 	case T_OBJECT:
+	case T_OBJECT_EX:
 		Py_XINCREF(v);
 		oldv = *(PyObject **)addr;
 		*(PyObject **)addr = v;