Convert Context and Connection to real types
diff --git a/src/ssl/connection.c b/src/ssl/connection.c
index 2d309cd..a5fdc51 100755
--- a/src/ssl/connection.c
+++ b/src/ssl/connection.c
@@ -1107,24 +1107,25 @@
 #undef ADD_ALIAS
 #undef ADD_METHOD
 
+static char ssl_Connection_doc[] = "\n\
+Connection(context, socket) -> Connection instance\n\
+\n\
+Create a new Connection object, using the given OpenSSL.SSL.Context instance\n\
+and socket.\n\
+\n\
+@param context: An SSL Context to use for this connection\n\
+@param socket: The socket to use for transport layer\n\
+";
 
 /*
- * Constructor for Connection objects
- *
- * Arguments: ctx  - An SSL Context to use for this connection
- *            sock - The socket to use for transport layer
- * Returns:   The newly created Connection object
+ * Initializer used by ssl_Connection_new and ssl_Connection_New.  *Not*
+ * tp_init.  This takes an already allocated ssl_ConnectionObj, a context, and
+ * a optionally a socket, and glues them all together.
  */
-ssl_ConnectionObj *
-ssl_Connection_New(ssl_ContextObj *ctx, PyObject *sock)
-{
-    ssl_ConnectionObj *self;
+static ssl_ConnectionObj*
+ssl_Connection_init(ssl_ConnectionObj *self, ssl_ContextObj *ctx, PyObject *sock) {
     int fd;
 
-    self = PyObject_GC_New(ssl_ConnectionObj, &ssl_Connection_Type);
-    if (self == NULL)
-        return NULL;
-
     Py_INCREF(ctx);
     self->context = ctx;
 
@@ -1166,9 +1167,6 @@
             SSL_set_fd(self->ssl, (SOCKET_T)fd);
         }
     }
-
-    PyObject_GC_Track(self);
-
     return self;
 
 error:
@@ -1179,6 +1177,49 @@
 }
 
 /*
+ * Constructor for Connection objects
+ *
+ * Arguments: ctx  - An SSL Context to use for this connection
+ *            sock - The socket to use for transport layer
+ * Returns:   The newly created Connection object
+ */
+ssl_ConnectionObj *
+ssl_Connection_New(ssl_ContextObj *ctx, PyObject *sock) {
+    ssl_ConnectionObj *self;
+
+    self = PyObject_GC_New(ssl_ConnectionObj, &ssl_Connection_Type);
+    if (self == NULL) {
+        return NULL;
+    }
+    self = ssl_Connection_init(self, ctx, sock);
+    if (self == NULL) {
+        return NULL;
+    }
+    PyObject_GC_Track((PyObject *)self);
+    return self;
+}
+
+static PyObject*
+ssl_Connection_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
+    ssl_ConnectionObj *self;
+    ssl_ContextObj *ctx;
+    PyObject *sock;
+    static char *kwlist[] = {"context", "socket", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Connection", kwlist,
+                                     &ssl_Context_Type, &ctx, &sock)) {
+        return NULL;
+    }
+
+    self = (ssl_ConnectionObj *)subtype->tp_alloc(subtype, 1);
+    if (self == NULL) {
+        return NULL;
+    }
+
+    return (PyObject *)ssl_Connection_init(self, ctx, sock);
+}
+
+/*
  * Find attribute
  *
  * Arguments: self - The Connection object
@@ -1265,12 +1306,12 @@
 PyTypeObject ssl_Connection_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "Connection",
+    "OpenSSL.SSL.Connection",
     sizeof(ssl_ConnectionObj),
     0,
     (destructor)ssl_Connection_dealloc,
     NULL, /* print */
-    (getattrfunc)ssl_Connection_getattr,
+    (getattrfunc)ssl_Connection_getattr, /* tp_getattr */
     NULL, /* setattr */
     NULL, /* compare */
     NULL, /* repr */
@@ -1284,25 +1325,47 @@
     NULL, /* setattro */
     NULL, /* as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
-    NULL, /* doc */
+    ssl_Connection_doc, /* doc */
     (traverseproc)ssl_Connection_traverse,
     (inquiry)ssl_Connection_clear,
+    NULL, /* tp_richcompare */
+    0, /* tp_weaklistoffset */
+    NULL, /* tp_iter */
+    NULL, /* tp_iternext */
+    ssl_Connection_methods, /* tp_methods */
+    NULL, /* tp_members */
+    NULL, /* tp_getset */
+    NULL, /* tp_base */
+    NULL, /* tp_dict */
+    NULL, /* tp_descr_get */
+    NULL, /* tp_descr_set */
+    0, /* tp_dictoffset */
+    NULL, /* tp_init */
+    NULL, /* tp_alloc */
+    ssl_Connection_new, /* tp_new */
 };
 
 
 /*
  * Initiailze the Connection part of the SSL sub module
  *
- * Arguments: dict - Dictionary of the OpenSSL.SSL module
+ * Arguments: dict - The OpenSSL.SSL module
  * Returns:   1 for success, 0 otherwise
  */
 int
-init_ssl_connection(PyObject *dict)
-{
-    ssl_Connection_Type.ob_type = &PyType_Type;
-    Py_INCREF(&ssl_Connection_Type);
-    if (PyDict_SetItemString(dict, "ConnectionType", (PyObject *)&ssl_Connection_Type) != 0)
+init_ssl_connection(PyObject *module) {
+
+    if (PyType_Ready(&ssl_Connection_Type) < 0) {
         return 0;
+    }
+
+    if (PyModule_AddObject(module, "Connection", (PyObject *)&ssl_Connection_Type) != 0) {
+        return 0;
+    }
+
+    if (PyModule_AddObject(module, "ConnectionType", (PyObject *)&ssl_Connection_Type) != 0) {
+        return 0;
+    }
 
     return 1;
 }
diff --git a/src/ssl/context.c b/src/ssl/context.c
index c1e1934..cb9aa88 100644
--- a/src/ssl/context.c
+++ b/src/ssl/context.c
@@ -236,14 +236,22 @@
 }
 
 
-
+static char ssl_Context_doc[] = "\n\
+Context(method) -> Context instance\n\
+\n\
+OpenSSL.SSL.Context instances define the parameters for setting up new SSL\n\
+connections.\n\
+\n\
+@param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or\n\
+               TLSv1_METHOD.\n\
+";
 
 static char ssl_Context_load_verify_locations_doc[] = "\n\
 Let SSL know where we can find trusted certificates for the certificate\n\
 chain\n\
 \n\
 @param cafile: In which file we can find the certificates\n\
-@param capath: In which directory we can find the certificates\r\
+@param capath: In which directory we can find the certificates\n\
 @return: None\n\
 ";
 static PyObject *
@@ -963,38 +971,33 @@
 };
 #undef ADD_METHOD
 
-
-/* Constructor, takes an int specifying which method to use */
 /*
- * Constructor for Context objects
- *
- * Arguments: i_method - The SSL method to use, one of the SSLv2_METHOD,
- *                       SSLv3_METHOD, SSLv23_METHOD and TLSv1_METHOD
- *                       constants.
- * Returns:   The newly created Context object
+ * Despite the name which might suggest otherwise, this is not the tp_init for
+ * the Context type.  It's just the common initialization code shared by the
+ * two _{Nn}ew functions below.
  */
-ssl_ContextObj *
-ssl_Context_New(int i_method)
-{
+static ssl_ContextObj*
+ssl_Context_init(ssl_ContextObj *self, int i_method) {
     SSL_METHOD *method;
-    ssl_ContextObj *self;
 
-    switch (i_method)
-    {
-        /* Too bad TLSv1 servers can't accept SSLv3 clients */
-        case ssl_SSLv2_METHOD:    method = SSLv2_method();  break;
-        case ssl_SSLv23_METHOD:   method = SSLv23_method(); break;
-        case ssl_SSLv3_METHOD:    method = SSLv3_method();  break;
-        case ssl_TLSv1_METHOD:    method = TLSv1_method();  break;
+    switch (i_method) {
+        case ssl_SSLv2_METHOD:
+            method = SSLv2_method();
+            break;
+        case ssl_SSLv23_METHOD:
+            method = SSLv23_method();
+            break;
+        case ssl_SSLv3_METHOD:
+            method = SSLv3_method();
+            break;
+        case ssl_TLSv1_METHOD:
+            method = TLSv1_method();
+            break;
         default:
             PyErr_SetString(PyExc_ValueError, "No such protocol");
             return NULL;
     }
 
-    self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
-    if (self == NULL)
-        return (ssl_ContextObj *)PyErr_NoMemory();
-
     self->ctx = SSL_CTX_new(method);
     Py_INCREF(Py_None);
     self->passphrase_callback = Py_None;
@@ -1016,23 +1019,46 @@
                                 SSL_MODE_AUTO_RETRY);
 
     self->tstate = NULL;
-    PyObject_GC_Track((PyObject *)self);
 
     return self;
 }
 
 /*
- * Find attribute
- *
- * Arguments: self - The Context object
- *            name - The attribute name
- * Returns:   A Python object for the attribute, or NULL if something went
- *            wrong
+ * This one is exposed in the CObject API.  I want to deprecate it.
  */
-static PyObject *
-ssl_Context_getattr(ssl_ContextObj *self, char *name)
-{
-    return Py_FindMethod(ssl_Context_methods, (PyObject *)self, name);
+ssl_ContextObj*
+ssl_Context_New(int i_method) {
+    ssl_ContextObj *self;
+
+    self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
+    if (self == NULL) {
+       return (ssl_ContextObj *)PyErr_NoMemory();
+    }
+    self = ssl_Context_init(self, i_method);
+    PyObject_GC_Track((PyObject *)self);
+    return self;
+}
+
+
+/*
+ * This one is the tp_new of the Context type.  It's great.
+ */
+static PyObject*
+ssl_Context_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
+    int i_method;
+    ssl_ContextObj *self;
+    static char *kwlist[] = {"method", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:Context", kwlist, &i_method)) {
+        return NULL;
+    }
+
+    self = (ssl_ContextObj *)subtype->tp_alloc(subtype, 1);
+    if (self == NULL) {
+        return NULL;
+    }
+
+    return (PyObject *)ssl_Context_init(self, i_method);
 }
 
 /*
@@ -1103,12 +1129,12 @@
 PyTypeObject ssl_Context_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "Context",
+    "OpenSSL.SSL.Context",
     sizeof(ssl_ContextObj),
     0,
-    (destructor)ssl_Context_dealloc,
+    (destructor)ssl_Context_dealloc, /* tp_dealloc */
     NULL, /* print */
-    (getattrfunc)ssl_Context_getattr,
+    NULL, /* tp_getattr */
     NULL, /* setattr */
     NULL, /* compare */
     NULL, /* repr */
@@ -1121,26 +1147,48 @@
     NULL, /* getattro */
     NULL, /* setattro */
     NULL, /* as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
-    NULL, /* doc */
-    (traverseproc)ssl_Context_traverse,
-    (inquiry)ssl_Context_clear,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    ssl_Context_doc, /* tp_doc */
+    (traverseproc)ssl_Context_traverse, /* tp_traverse */
+    (inquiry)ssl_Context_clear, /* tp_clear */
+    NULL, /* tp_richcompare */
+    0, /* tp_weaklistoffset */
+    NULL, /* tp_iter */
+    NULL, /* tp_iternext */
+    ssl_Context_methods, /* tp_methods */
+    NULL, /* tp_members */
+    NULL, /* tp_getset */
+    NULL, /* tp_base */
+    NULL, /* tp_dict */
+    NULL, /* tp_descr_get */
+    NULL, /* tp_descr_set */
+    0, /* tp_dictoffset */
+    NULL, /* tp_init */
+    NULL, /* tp_alloc */
+    ssl_Context_new, /* tp_new */
 };
 
 
 /*
  * Initialize the Context part of the SSL sub module
  *
- * Arguments: dict - Dictionary of the OpenSSL.SSL module
+ * Arguments: dict - The OpenSSL.SSL module
  * Returns:   1 for success, 0 otherwise
  */
 int
-init_ssl_context(PyObject *dict)
-{
-    ssl_Context_Type.ob_type = &PyType_Type;
-    Py_INCREF(&ssl_Context_Type);
-    if (PyDict_SetItemString(dict, "ContextType", (PyObject *)&ssl_Context_Type) != 0)
+init_ssl_context(PyObject *module) {
+
+    if (PyType_Ready(&ssl_Context_Type) < 0) {
         return 0;
+    }
+
+    if (PyModule_AddObject(module, "Context", (PyObject *)&ssl_Context_Type) < 0) {
+        return 0;
+    }
+
+    if (PyModule_AddObject(module, "ContextType", (PyObject *)&ssl_Context_Type) < 0) {
+        return 0;
+    }
 
     return 1;
 }
diff --git a/src/ssl/ssl.c b/src/ssl/ssl.c
index 2b8402d..94d4844 100644
--- a/src/ssl/ssl.c
+++ b/src/ssl/ssl.c
@@ -42,51 +42,9 @@
          *ssl_WantX509LookupError,     /* ...                     */
          *ssl_SysCallError;            /* Uses (errno,errstr)     */
 
-static char ssl_Context_doc[] = "\n\
-The factory function inserted in the module dictionary to create Context\n\
-objects\n\
-\n\
-@param method: The SSL method to use\n\
-@return: The Context object\n\
-";
-
-static PyObject *
-ssl_Context(PyObject *spam, PyObject *args)
-{
-    int method;
-
-    if (!PyArg_ParseTuple(args, "i:Context", &method))
-        return NULL;
-
-    return (PyObject *)ssl_Context_New(method);
-}
-
-static char ssl_Connection_doc[] = "\n\
-The factory function inserted in the module dictionary to create Connection\n\
-objects\n\
-\n\
-@param ctx: An SSL Context to use for this connection\n\
-@param sock: The socket to use for transport layer\n\
-@return: The Connection object\n\
-";
-
-static PyObject *
-ssl_Connection(PyObject *spam, PyObject *args)
-{
-    ssl_ContextObj *ctx;
-    PyObject *sock;
-
-    if (!PyArg_ParseTuple(args, "O!O:Connection", &ssl_Context_Type, &ctx, &sock))
-        return NULL;
-
-    return (PyObject *)ssl_Connection_New(ctx, sock);
-}
-
 
 /* Methods in the OpenSSL.SSL module */
 static PyMethodDef ssl_methods[] = {
-    { "Context",        ssl_Context,    METH_VARARGS, ssl_Context_doc },
-    { "Connection",     ssl_Connection, METH_VARARGS, ssl_Connection_doc },
     { NULL, NULL }
 };
 
@@ -101,15 +59,16 @@
 {
     static void *ssl_API[ssl_API_pointers];
     PyObject *ssl_api_object;
-    PyObject *module, *dict;
+    PyObject *module;
 
     SSL_library_init();
     ERR_load_SSL_strings();
 
     import_crypto();
 
-    if ((module = Py_InitModule3("SSL", ssl_methods, ssl_doc)) == NULL)
+    if ((module = Py_InitModule3("SSL", ssl_methods, ssl_doc)) == NULL) {
         return;
+    }
 
     /* Initialize the C API pointer array */
     ssl_API[ssl_Context_New_NUM]    = (void *)ssl_Context_New;
@@ -206,10 +165,9 @@
     PyModule_AddIntConstant(module, "SENT_SHUTDOWN", SSL_SENT_SHUTDOWN);
     PyModule_AddIntConstant(module, "RECEIVED_SHUTDOWN", SSL_RECEIVED_SHUTDOWN);
 
-    dict = PyModule_GetDict(module);
-    if (!init_ssl_context(dict))
+    if (!init_ssl_context(module))
         goto error;
-    if (!init_ssl_connection(dict))
+    if (!init_ssl_connection(module))
         goto error;
 
 #ifdef WITH_THREAD